In [1]:
# Para visualización en notebook
import matplotlib.pyplot as plt
import matplotlib as mpl
import seaborn as sns

# Parámetros de visualización
sns.set_context('talk')
mpl.rcParams['figure.figsize'] = (8, 6)


import os
from collections import Counter

# Números y Datos
import numpy as np
import pandas as pd

import networkx as nx
from networkx.algorithms.approximation import average_clustering

from glob import glob
from pathlib import Path
In [6]:
import urllib.request

url = "https://www.dropbox.com/scl/fi/nk8yvhez5ylhd6blzf77o/airport.txt?rlkey=3cf24r6yij8uu0fakb68yztlm&dl=1"
urllib.request.urlretrieve(url, "airport.txt")
print("Descarga completa: airport.txt")

url = "https://www.dropbox.com/scl/fi/t62q9swnah7nvu34falkj/celegans.txt?rlkey=lxg2kashijntfi0bwmeuty5ja&dl=1"
urllib.request.urlretrieve(url, "celegans.txt")
print("Descarga completa: celegans.txt")

url = "https://www.dropbox.com/scl/fi/eebzjgqazi8b02bkkrxmf/airStrongly_positions.pkl?rlkey=cyhifzsgrls5vdlycrb1gnykv&st=6lozmqe6&dl=1"
urllib.request.urlretrieve(url, "airportStronglyConn_pos.pkl")
print("Descarga completa: airportStronglyConn_pos.pkl")
Descarga completa: airport.txt
Descarga completa: celegans.txt
Descarga completa: airportStronglyConn_pos.pkl
In [2]:
# DATOS REDES:
#!wget -O airport.txt https://www.dropbox.com/scl/fi/nk8yvhez5ylhd6blzf77o/airport.txt?rlkey=3cf24r6yij8uu0fakb68yztlm&dl=1
#!wget -O facebook.txt https://www.dropbox.com/scl/fi/hdgcmyss47w9t676kh2ug/facebook.txt?rlkey=j616y86ejfn6f719jg4b8e413&dl=1
#!wget -O lesmiserables.txt https://www.dropbox.com/scl/fi/ex7183k4zjgxbiw0diwi3/lesmiserables.txt?rlkey=zx5u5371s7gw3jlv50363jycf&dl=1
#!wget -O terrorist.txt https://www.dropbox.com/scl/fi/2vl6hcazv5v13r7scodod/terrorist.txt?rlkey=l0n1rxbby6a8irtlyh1tbbweo&dl=1
#!wget -O celegans.txt https://www.dropbox.com/scl/fi/t62q9swnah7nvu34falkj/celegans.txt?rlkey=lxg2kashijntfi0bwmeuty5ja&dl=1
#!wget -O email.txt https://www.dropbox.com/scl/fi/w5o34b0olg7xek4s42lml/email-Eu-core.txt?rlkey=g2561imdd4ssyrwfgywrotzwm&st=czqgmef0&dl=1
#!wget -O email_labels.txt  https://www.dropbox.com/scl/fi/ij3b6jul7ispiovt18sfm/email-Eu-core-department-labels.txt?rlkey=dqp60qw20pw7biil9cvti4u68&st=zij9wsi8&dl=1


# AHORA ARCHIVOS DE POSICION DE LOS NODOS:
#!wget -O airportStronglyConn_pos.pkl https://www.dropbox.com/scl/fi/eebzjgqazi8b02bkkrxmf/airStrongly_positions.pkl?rlkey=cyhifzsgrls5vdlycrb1gnykv&st=6lozmqe6&dl=1
#!wget -O email_pos.pkl https://www.dropbox.com/scl/fi/loeuul6gxq7uscd1m7ks8/email_positions.pkl?rlkey=caf194s8198pffo2zaq6767jz&st=kw0c3tu4&dl=1
#!wget -O fb_pos.pkl https://www.dropbox.com/scl/fi/ka6v0h9ew5j08haxlbf6b/fb_positions.pkl?rlkey=7ul7jr7re5bziy54cgp3x9tre&st=vp6gjciw&dl=1
'wget' is not recognized as an internal or external command,
operable program or batch file.
'dl' is not recognized as an internal or external command,
operable program or batch file.
'wget' is not recognized as an internal or external command,
operable program or batch file.
'dl' is not recognized as an internal or external command,
operable program or batch file.
'wget' is not recognized as an internal or external command,
operable program or batch file.
'st' is not recognized as an internal or external command,
operable program or batch file.
'dl' is not recognized as an internal or external command,
operable program or batch file.
In [8]:
def read_graph(filename):
    G = nx.Graph()
    array = np.loadtxt(filename, dtype=int)
    G.add_edges_from(array)
    return G


def read_graph_weighted(filename):
    G = nx.Graph()
    array = np.loadtxt(filename, dtype=int)
    G.add_weighted_edges_from(array)
    return G

def read_dir_graph(filename):
    G = nx.DiGraph()
    array = np.loadtxt(filename, dtype=int)
    G.add_edges_from(array)
    return G

def read_dir_graph_weighted(filename):
    G = nx.DiGraph()
    array = np.loadtxt(filename, dtype=int)
    G.add_weighted_edges_from(array)
    return G
In [9]:
celegans= read_graph_weighted('celegans.txt')
print('C. elegans')
print(celegans)
print('Es dirigido?:',nx.is_directed(celegans))
print('Es pesado?:',nx.is_weighted(celegans))
print('Es conectado?:',nx.is_connected(celegans))
print('')

air = read_dir_graph_weighted('airport.txt')
print('Airport')
print(air)
print('Es dirigido?:',nx.is_directed(air))
print('Es pesado?:',nx.is_weighted(air))
print('Es fuertemente conexo?:',nx.is_strongly_connected(air))
print('Es debilmente conexo?:',nx.is_weakly_connected(air))
C. elegans
Graph with 297 nodes and 2148 edges
Es dirigido?: False
Es pesado?: True
Es conectado?: True

Airport
DiGraph with 1574 nodes and 28236 edges
Es dirigido?: True
Es pesado?: True
Es fuertemente conexo?: False
Es debilmente conexo?: False
In [10]:
# Definición de Funciones
'''
Permite obtener una Matriz de Adyacencia Pesada (MAP)
a partir de los datos contenidos en el archivo especificado
Substrae una matriz diagonal de 1s para evitar conexiones
reflexivas (un nodo consigo mismo)
'''
def obtener_map(nombre_archivo):
    df = pd.read_csv(nombre_archivo, header=None)
    matAdyacPesada = df.values
    n = matAdyacPesada.shape[0]
    matAdyacPesada -= np.diag(np.ones(n))
    return matAdyacPesada

'''
Crea un heatmap a partir de una matriz
'''
def graficar_heatmap(matriz, titulo=''):
    sns.heatmap(matriz)
    n = matriz.shape[0]
    plt.xlim(0, n)
    plt.ylim(0, n)
    plt.title(titulo)
    plt.show()

'''
Exporta un archivo de imagen
de un heatmap obtenido a partir de una matriz
'''
def exportar_heatmap(matriz, nombre_archivo='imagen_01.png'):
    sns.heatmap(matriz)
    n = matriz.shape[0]
    plt.xlim(0, n)
    plt.ylim(0, n)
    plt.savefig(nombre_archivo, dpi=300, bbox_inches='tight')
    plt.close()

'''
Data una matriz de adyacencia pesada y un valor
de densidad de enlaces, calcula el valor umbral
necesario para representar valores que estén
por encima de la densidad de enlaces dada
'''
def densidad_a_umbral(matriz, densidad=0.1):
    n = matriz.shape[0]
    tril_idx = np.tril_indices(n, -1)
    c = sorted(np.array(list(matriz[tril_idx].reshape(-1))), reverse=True)
    return c[int((len(c)-1)*densidad)]

'''
Permite representar un grafo
'''
def representar_grafo(G, titulo='', zip_de_layout=None, mostrar_etiquetas=True, nombre_archivo=None):
    plt.figure(figsize=(8, 6))
    plt.title(titulo, fontsize=14)
    nx.draw(G, zip_de_layout, with_labels=mostrar_etiquetas, node_size=25, width=0.1, linewidths=0.25)
    if not nombre_archivo == None:
        plt.savefig(nombre_archivo, dpi=300, bbox_inches='tight')
    plt.show()

'''
Permite representar un grafo a partir de una matriz
de Adyacencia - Agrega una escala de colores para los
nodos, que refleja el grado
Paletas disponibles: plt.cm.{Grays|Blues|BuGn|PuRd|Oranges}
'''
def representar_grafo_escala_colores(G, escala_color='grados', titulo='', zip_de_layout=None, mostrar_etiquetas=False, nombre_archivo=None):
    if escala_color == 'grados':
        valores_escala = dict(G.degree())
    elif escala_color == 'clustering':
        valores_escala = nx.clustering(G)
    nodos = G.nodes()
    n = len(list(nodos))
    n_color = np.asarray([valores_escala[n] for n in nodos])
    vmin = min(n_color)
    vmax = max(n_color)
    cmap = plt.cm.Oranges
    norm = plt.Normalize(vmin = vmin, vmax=vmax)
    plt.figure(figsize=(9,6))
    plt.title(titulo, fontsize=14)
    nx.draw(G, zip_de_layout, node_size=25, node_color=n_color, width=0.1, linewidths=0.25, vmin=vmin, vmax=vmax,cmap=cmap)
    sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)
    plt.colorbar(sm, ax=plt.gca())
    if not nombre_archivo==None:
        plt.savefig(nombre_archivo, dpi=300, bbox_inches='tight')
    plt.show()

'''
En Grafos dirigidos, permite obtener la mayor componente altamente conexa
'''
def obtener_mayor_componente_fuertemente_conexa(G):
    if nx.is_directed(G):
        StronglyCC = sorted(nx.strongly_connected_components(G), key=len, reverse=True)
        return G.subgraph(StronglyCC[0])
    else:
        return None

'''
Calcula el diámetro del Grafo teniendo en cuenta:
    Si la red es no dirigida:
        Si la red es conexa, devuelve el diametro directo
        Si no es conexa devuelve el diámetro de la componente gigante
    Si la red es dirigida:
        Si está fuertemente conectada devuelve el diametro
        Si no está fuertemente conectada, devuelve el diámetro de la mayor componente fuertemente conectada
'''
def calcular_diametro(G):
    if not nx.is_directed(G):
        if nx.is_connected(G):
            print("La red no dirigida y conexa, obteniendo diámetro en forma directa")
            D = nx.diameter(G)
        else:
            print("La red es no dirigida y no es conexa. Retornando el diámetro de la componente gigante.")
            gigante = G.subgraph(max(nx.connected_components(G), key=len)).copy()
            D = nx.diameter(gigante)
    else:
        if nx.is_strongly_connected(G):
            print("La red es dirigida y fuertemente conexa, obteniendo diámetro en forma directa")
            D = nx.diameter(G)
        else:
            largest_scc = max(nx.strongly_connected_components(G), key=len)
            G_scc = G.subgraph(largest_scc).copy()
            print("La red es dirigida y no fuertemente conexa, obteniendo diámetro de la mayor componente fuertemente conexa")
            D = nx.diameter(G_scc)

    return D

'''
Para redes muy grandes, calcula la distancia media por sampleo
tomando n pares de nodos, calculando entre ellos la distancia más
corta y luego promediando.
Utilizo el decorator @retry porque en ciertos ejemplos, uno o más pares de nodos
elegidos pueden no estar conectados y luego su camino no está definido, arrojando
una excepción. Retry me permite avanzar desestimando el error
'''
def calcular_distancia_media_y_eff_por_sampleo(G, numero_muestras=100):

    nodos = list(G)
    if numero_muestras > len(nodos):
        numero_muestras = len(nodos)

    if numero_muestras > 100000:
        numero_muestras = 100000

    pares = np.random.choice(nodos, (numero_muestras, 2))
    distancias = [nx.shortest_path_length(G, *par)
               for par in pares]
    inversas = [(1/nx.shortest_path_length(G, *par))
               for par in pares]
    return np.mean(distancias), np.mean(inversas)


'''
Devuelve el grado promedio y el nodo con mayor grado
'''
def calcular_grados(matriz, densidad=0.1):
    G = nx.from_numpy_array(matriz)
    if nx.is_weighted(G):
        umbral = densidad_a_umbral(matriz, densidad)
        G = nx.from_numpy_array(matriz >= umbral)
    else:
        G = nx.from_numpy_array(matriz)
    grados = [G.degree(n) for n in G.nodes()]
    promedio = np.mean(grados)
    nodo_max = max(G.degree(), key=lambda x: x[1])
    return promedio, nodo_max

'''
Analiza y reporta varios parametros de los grafos
'''
def analizar_grafo(G):

    print('Es un grafo dirigido?:',nx.is_directed(G))
    print('Es un grafo pesado?:',nx.is_weighted(G))
    if not nx.is_directed(G):
        print('Es un grafo conectado?:',nx.is_connected(G))
    else:
        print('Grafo dirigido no acepta definición de conexo')

    diametro = calcular_diametro(G)
    print(f"Diámetro: {diametro}")

    if nx.is_directed(G):
        print('Es un grafo fuertemente conexo?:',nx.is_strongly_connected(G))
        print('Es un grafo debilmente conexo?:',nx.is_weakly_connected(G))
        componente_mayor_fuertemente_conexa = obtener_mayor_componente_fuertemente_conexa(G)
        print("Componente mayor fuertemente conexa")
        print(componente_mayor_fuertemente_conexa)
    else:
        print("Por no ser dirigido no acepta determinación de fuertemente o débilmente conexo")


    # Por si es dirigido tenemos que hacer esto
    # Cálculo de distancia media
    if nx.is_directed(G):
        H = G.to_undirected()
        print("El grafo no es conexo, calculando la distancia media y la eficiencia de la componente gigante")
        print("Esta es una lista de las componentes conexas y su distancia media")
        for componente_nodos in nx.connected_components(H):
            subgrafo = H.subgraph(componente_nodos)
            n = subgrafo.number_of_nodes()
            if nx.is_connected(subgrafo) and n > 1:
                L = nx.average_shortest_path_length(subgrafo)
                print(f"- Componente de {n} nodos con distancia media: {L:.3f}")
            #elif n == 1:
            #    print(f"- Componente aislada de 1 nodo (sin distancia definida)")

        gigante = H.subgraph(max(nx.connected_components(H), key=len)).copy()
        distancia_media_directa = nx.average_shortest_path_length(gigante)
        nodos_gigante = gigante.number_of_nodes()
        print(f"La componente Gigante tiene {nodos_gigante} nodos")
        eficiencia_directa = nx.global_efficiency(gigante)
        distancia_media_sampleo, eficiencia_sampleo = calcular_distancia_media_y_eff_por_sampleo(gigante)
        print(f"Distancia Media  de la Componente Gigante obtenida por muestreo: {distancia_media_sampleo}")
        print(f"Distancia Media Directa de la Componente Gigante: {distancia_media_directa}")
        print(f"Eficiencia Global de la Componente Gigante obtenida por muestreo: {eficiencia_sampleo}")
        print(f"Eficiencia Global Directa de la Componente Gigante: {eficiencia_directa}")
        eficiencia_directa = nx.global_efficiency(H)
        print(f"Eficiencia Global Directa del Grafo: {eficiencia_directa}")


    elif nx.is_connected(G):
        distancia_media_directa = nx.average_shortest_path_length(G)
        distancia_media_sampleo, eficiencia_sampleo = calcular_distancia_media_y_eff_por_sampleo(G)
        print(f"Distancia Media del Grafo obtenida por muestreo: {distancia_media_sampleo}")
        print(f"Distancia Media Diecta del Grafo: {distancia_media_directa}")
        print(f"Eficiencia Global Del Grafo obtenida por muestreo: {eficiencia_sampleo}")
        eficiencia_directa = nx.global_efficiency(G)
        print(f"Eficiencia Global Directa del Grafo: {eficiencia_directa}")
    else:
        print("El grafo no es conexo, calculando la distancia media y la eficiencia de la componente gigante")
        print("Esta es una lista de las componentes conexas y su distancia media")
        for componente_nodos in nx.connected_components(G):
            subgrafo = G.subgraph(componente_nodos)
            n = subgrafo.number_of_nodes()
            if nx.is_connected(subgrafo) and n > 1:
                L = nx.average_shortest_path_length(subgrafo)
                print(f"- Componente de {n} nodos con distancia media: {L:.3f}")
            #elif n == 1:
            #    print(f"- Componente aislada de 1 nodo (sin distancia definida)")

        gigante = G.subgraph(max(nx.connected_components(G), key=len)).copy()
        distancia_media_directa = nx.average_shortest_path_length(gigante)
        nodos_gigante = gigante.number_of_nodes()
        print(f"La componente Gigante tiene {nodos_gigante} nodos")
        eficiencia_directa = nx.global_efficiency(gigante)
        distancia_media_sampleo, eficiencia_sampleo = calcular_distancia_media_y_eff_por_sampleo(gigante)
        print(f"Distancia Media  de la Componente Gigante obtenida por muestreo: {distancia_media_sampleo}")
        print(f"Distancia Media Directa de la Componente Gigante: {distancia_media_directa}")
        print(f"Eficiencia Global de la Componente Gigante obtenida por muestreo: {eficiencia_sampleo}")
        print(f"Eficiencia Global Directa de la Componente Gigante: {eficiencia_directa}")
        eficiencia_directa = nx.global_efficiency(G)
        print(f"Eficiencia Global Directa del Grafo: {eficiencia_directa}")



def graficar_distribucion_grados(G, bins=10, titulo='Distribución de Grados', nombre_archivo=None):
    plt.figure(figsize=(6, 4))
    grados = [G.degree(n) for n in G.nodes()]
    hist, bins, _ = plt.hist(grados, bins=bins, density=True)
    plt.xlabel('k')
    plt.ylabel('p(k)')
    plt.title(titulo)
    if not nombre_archivo == None:
        plt.savefig(nombre_archivo, dpi=300, bbox_inches='tight')
    plt.show()

def graficar_distribucion_grados_normalizada(G, bins=10, titulo='Distribución de Grado Normalizada', nombre_archivo=None):
    grados = [G.degree(n) for n in G.nodes()]
    conteo = Counter(grados)
    total_nodos = G.number_of_nodes()

    # Crear distribución normalizada
    grados_k = sorted(conteo.keys())
    pk = [conteo[k] / total_nodos for k in grados_k]

    # Graficar
    plt.figure(figsize=(6, 4))
    plt.bar(grados_k, pk, width=0.8, color='skyblue', edgecolor='black')
    #plt.hist(grados_k, bins=bins, density=True)
    plt.xlabel('Grado k')
    plt.ylabel('p(k)')
    plt.title(titulo)

    if nombre_archivo:
        plt.savefig(nombre_archivo, dpi=300, bbox_inches='tight')

    plt.show()

def read_graph(filename):
    G = nx.Graph()
    array = np.loadtxt(filename, dtype=int)
    G.add_edges_from(array)
    return G

def read_graph_weighted(filename):
    G = nx.Graph()
    array = np.loadtxt(filename, dtype=int)
    G.add_weighted_edges_from(array)
    return G

def read_dir_graph(filename):
    G = nx.DiGraph()
    array = np.loadtxt(filename, dtype=int)
    G.add_edges_from(array)
    return G

def read_dir_graph_weighted(filename):
    G = nx.DiGraph()
    array = np.loadtxt(filename, dtype=int)
    G.add_weighted_edges_from(array)
    return G
In [11]:
print("=== C. elegans ===")
G_ce = read_graph_weighted('celegans.txt')
print(G_ce)
analizar_grafo(G_ce)
=== C. elegans ===
Graph with 297 nodes and 2148 edges
Es un grafo dirigido?: False
Es un grafo pesado?: True
Es un grafo conectado?: True
La red no dirigida y conexa, obteniendo diámetro en forma directa
Diámetro: 5
Por no ser dirigido no acepta determinación de fuertemente o débilmente conexo
Distancia Media del Grafo obtenida por muestreo: 2.52
Distancia Media Diecta del Grafo: 2.455318955318955
Eficiencia Global Del Grafo obtenida por muestreo: 0.4341666666666668
Eficiencia Global Directa del Grafo: 0.4448228531562069
In [62]:
# Matriz de adyacencia pesada (reemplaza con tu archivo real si difiere)
mat_ce = nx.to_numpy_array(G_ce, weight='weight')
np.fill_diagonal(mat_ce, 0)

# Heatmap
mat_ce = nx.to_numpy_array(G_ce, weight='weight')
np.fill_diagonal(mat_ce, 0)

# Heatmap y export
graficar_heatmap(mat_ce, titulo='Heatmap C. elegans')
exportar_heatmap(mat_ce, nombre_archivo='heatmap_celegans.png')

# Umbral (10%)
umbral_ce = densidad_a_umbral(mat_ce, densidad=0.1)
print(f'Umbral C. elegans (10% densidad): {umbral_ce}')

# Layout y representación del grafo
pos_ce = nx.spring_layout(G_ce, seed=42)
representar_grafo(G_ce, titulo='C. elegans (estructura)', zip_de_layout=pos_ce)
representar_grafo_escala_colores(
    G_ce,
    escala_color='grados',
    titulo='C. elegans (grado de nodo)',
    zip_de_layout=pos_ce
)

# Distribución de grados
graficar_distribucion_grados(G_ce, bins=20, titulo='Distribución de grados (C. elegans)')
graficar_distribucion_grados_normalizada(
    G_ce, bins=20, titulo='Distribución normalizada de grados (C. elegans)'
)
Umbral C. elegans (10% densidad): 0.0
In [13]:
# -------------------------------------------------
# Análisis para Airport
# -------------------------------------------------
print("\n=== Airport ===")
G_air = read_dir_graph_weighted('airport.txt')
print(G_air)
analizar_grafo(G_air)
=== Airport ===
DiGraph with 1574 nodes and 28236 edges
Es un grafo dirigido?: True
Es un grafo pesado?: True
Grafo dirigido no acepta definición de conexo
La red es dirigida y no fuertemente conexa, obteniendo diámetro de la mayor componente fuertemente conexa
Diámetro: 9
Es un grafo fuertemente conexo?: False
Es un grafo debilmente conexo?: False
Componente mayor fuertemente conexa
DiGraph with 1402 nodes and 28032 edges
El grafo no es conexo, calculando la distancia media y la eficiencia de la componente gigante
Esta es una lista de las componentes conexas y su distancia media
- Componente de 1572 nodos con distancia media: 3.115
- Componente de 2 nodos con distancia media: 1.000
La componente Gigante tiene 1572 nodos
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
Cell In[13], line 7
      5 G_air = read_dir_graph_weighted('airport.txt')
      6 print(G_air)
----> 7 analizar_grafo(G_air)

Cell In[10], line 213, in analizar_grafo(G)
    211 print(f"La componente Gigante tiene {nodos_gigante} nodos")
    212 eficiencia_directa = nx.global_efficiency(gigante)
--> 213 distancia_media_sampleo, eficiencia_sampleo = calcular_distancia_media_y_eff_por_sampleo(gigante)
    214 print(f"Distancia Media  de la Componente Gigante obtenida por muestreo: {distancia_media_sampleo}")
    215 print(f"Distancia Media Directa de la Componente Gigante: {distancia_media_directa}")

Cell In[10], line 148, in calcular_distancia_media_y_eff_por_sampleo(G, numero_muestras)
    145 pares = np.random.choice(nodos, (numero_muestras, 2))
    146 distancias = [nx.shortest_path_length(G, *par)
    147            for par in pares]
--> 148 inversas = [(1/nx.shortest_path_length(G, *par))
    149            for par in pares]
    150 return np.mean(distancias), np.mean(inversas)

Cell In[10], line 148, in <listcomp>(.0)
    145 pares = np.random.choice(nodos, (numero_muestras, 2))
    146 distancias = [nx.shortest_path_length(G, *par)
    147            for par in pares]
--> 148 inversas = [(1/nx.shortest_path_length(G, *par))
    149            for par in pares]
    150 return np.mean(distancias), np.mean(inversas)

ZeroDivisionError: division by zero
In [64]:
# Matriz de adyacencia pesada (reemplaza con tu archivo real si difiere)
#mat_air = obtener_map(G_air)

import networkx as nx
import numpy as np
import pandas as pd

# convierte G_air en un DataFrame N×N con los pesos
df_adj = nx.to_pandas_adjacency(G_air, dtype=float, weight='weight')
# fuerza ceros en la diagonal (quita self‐loops)
np.fill_diagonal(df_adj.values, 0)

# si quieres, guardas en CSV para reusar obtener_map:
df_adj.to_csv('airport_adj.csv', header=False, index=False)

# y ya:
mat_air = df_adj.values



# Heatmap
graficar_heatmap(mat_air, titulo='Heatmap Airport')
#exportar_heatmap(mat_air, nombre_archivo='heatmap_airport.png')

# Umbral para un 10% de densidad
umbral_air = densidad_a_umbral(mat_air, densidad=0.1)
print(f'Umbral (10%): {umbral_air}')

# Layout y representación del grafo
pos_air = nx.spring_layout(G_air, seed=42)
representar_grafo(G_air, titulo='Airport (estructura)', zip_de_layout=pos_air, mostrar_etiquetas=False)
representar_grafo_escala_colores(
    G_air,
    escala_color='clustering',
    titulo='Airport (coeficiente de clustering)',
    zip_de_layout=pos_air,
    mostrar_etiquetas=False
)

# Distribución de grados
graficar_distribucion_grados(G_air, bins=20, titulo='Distribución de grados (Airport)')
graficar_distribucion_grados_normalizada(
    G_air, bins=20, titulo='Distribución normalizada de grados (Airport)'
)
Umbral (10%): 0.0
In [15]:
import pickle
import matplotlib.pyplot as plt
import networkx as nx

# 1) Carga el grafo dirigido y ponderado
G_air = read_dir_graph_weighted('airport.txt')

# 2) Extrae la mayor componente fuertemente conexa (tu propia función)
H = obtener_mayor_componente_fuertemente_conexa(G_air)

# 3) Carga el dict de posiciones desde el .pkl
with open('airportStronglyConn_pos.pkl', 'rb') as f:
    pos = pickle.load(f)
# pos debe ser un dict { nodo: (x, y), ... }

# 4) Dibuja:
plt.figure(figsize=(12, 12))
nx.draw_networkx_nodes(H, pos,
                       node_size=10,
                       node_color='steelblue',
                       alpha=0.7)
nx.draw_networkx_edges(H, pos,
                       edge_color='gray',
                       width=0.3,
                       arrowsize=2,
                       alpha=0.5)
plt.title("Subgrafo fuertemente conexo de Airport")
plt.axis('off')
plt.show()
In [17]:
import numpy as np
import networkx as nx

def plotWeightedGraph(G, pos, colorMapping, magnification, nodeSize=45):
    # 1) nodos con color por mapping
    values = [ colorMapping.get(n, 0.0) for n in G.nodes() ]
    nx.draw_networkx_nodes(G, pos=pos,
                           node_size=nodeSize,
                           node_color=values)

    # 2) etiquetas (puedes quitar esta línea si sobra)
    nx.draw_networkx_labels(G, pos,
                            labels={n: n for n in G.nodes()},
                            font_size=7,
                            font_color='white')

    # 3) grosores de arista según peso
    #   obtenemos la lista de pesos en el mismo orden que G.edges()
    weights = [ G[u][v].get('weight', 1.0) for u, v in G.edges() ]
    edgeWidths = np.array(weights, dtype=float)

    if edgeWidths.max() > 0:
        edgeWidths = magnification * (edgeWidths / edgeWidths.max())
        # desplazamos mínimo a 0.5 para que se vean todas las aristas
        edgeWidths = edgeWidths - edgeWidths.min() + 0.5
    else:
        edgeWidths = np.full_like(edgeWidths, 0.5)

    nx.draw_networkx_edges(G, pos,
                           edgelist=G.edges(),
                           width=edgeWidths,
                           edge_color='gray')

# --- Ejemplo de uso ---

# 1) Carga el grafo completo
G_air = read_dir_graph_weighted('airport.txt')

# 2) Extrae la componente fuertemente conexa
H_air = obtener_mayor_componente_fuertemente_conexa(G_air)

# 3) Carga las posiciones de esa componente
with open('airportStronglyConn_pos.pkl','rb') as f:
    pos_air = pickle.load(f)

# 4) Centralidad de H_air, no de G_air
cent_air = nx.degree_centrality(H_air)

# 5) Dibuja solo H_air con pos_air
plotWeightedGraph(H_air, pos_air, cent_air,
                  magnification=10, nodeSize=60)
In [ ]:
# Para C. elegans:
G_ce = read_graph_weighted('celegans.txt')
pos_ce = nx.spring_layout(G_ce, seed=42)
cent_ce = nx.degree_centrality(G_ce)
plotWeightedGraph(G_ce, pos_ce, cent_ce, magnification=10, nodeSize=45)
In [18]:
import networkx as nx
import matplotlib.pyplot as plt
import pickle

def plot_centrality_with_colorbar(G, pos, centrality, title, cmap=plt.cm.plasma):
    """
    Dibuja G usando 'pos', coloreando y escalando nodos según 'centrality',
    y añade una barra de colores.
    """
    # Preparamos valores normalizados y tamaños
    vals = list(centrality.values())
    norm_vals = [(v - min(vals)) / (max(vals) - min(vals) + 1e-6) for v in vals]
    sizes = [100 + 900 * v for v in norm_vals]

    fig, ax = plt.subplots(figsize=(6,6))
    nodes = nx.draw_networkx_nodes(
        G, pos,
        node_size=sizes,
        node_color=vals,
        cmap=cmap,
        ax=ax
    )
    nx.draw_networkx_edges(G, pos, alpha=0.3, ax=ax)
    ax.set_title(title)
    ax.axis('off')

    # Escala de colores
    sm = plt.cm.ScalarMappable(
        cmap=cmap,
        norm=plt.Normalize(vmin=min(vals), vmax=max(vals))
    )
    sm.set_array([])
    cbar = fig.colorbar(sm, ax=ax, fraction=0.046, pad=0.04)
    cbar.set_label('Centralidad', rotation=270, labelpad=15)

    plt.show()


# --- 1) Grafo dirigido: Airport (componente fuertemente conexa) ---
G_air = read_dir_graph_weighted('airport.txt')
H_air = obtener_mayor_componente_fuertemente_conexa(G_air)
with open('airportStronglyConn_pos.pkl','rb') as f:
    pos_air = pickle.load(f)

# Calculamos dos medidas de centralidad
deg_air = nx.degree_centrality(H_air)    # grado (in+out)
pr_air  = nx.pagerank(H_air, weight='weight')

# Dibujamos cada una con su colorbar
plot_centrality_with_colorbar(H_air, pos_air, deg_air, 
    "Airport: Degree Centrality")
plot_centrality_with_colorbar(H_air, pos_air, pr_air, 
    "Airport: PageRank")
In [19]:
# --- 2) Grafo no dirigido: C. elegans ---
G_ce = read_graph_weighted('celegans.txt')
pos_ce = nx.spring_layout(G_ce, iterations=1000, seed=42)

deg_ce = nx.degree_centrality(G_ce)
btw_ce = nx.betweenness_centrality(G_ce, weight='weight', normalized=True)

plot_centrality_with_colorbar(G_ce, pos_ce, deg_ce, 
    "C. elegans: Degree Centrality")
plot_centrality_with_colorbar(G_ce, pos_ce, btw_ce, 
    "C. elegans: Betweenness Centrality")
In [21]:
!pip install powerlaw
Collecting powerlaw
  Obtaining dependency information for powerlaw from https://files.pythonhosted.org/packages/e8/26/e0daa306f83d705bc1ed4d6759b7fc945cc787530c230ee1fe299cc28093/powerlaw-1.5-py3-none-any.whl.metadata
  Downloading powerlaw-1.5-py3-none-any.whl.metadata (9.3 kB)
Requirement already satisfied: scipy in c:\users\benja\anaconda3\lib\site-packages (from powerlaw) (1.10.1)
Requirement already satisfied: numpy in c:\users\benja\anaconda3\lib\site-packages (from powerlaw) (1.24.3)
Requirement already satisfied: matplotlib in c:\users\benja\anaconda3\lib\site-packages (from powerlaw) (3.7.1)
Requirement already satisfied: mpmath in c:\users\benja\anaconda3\lib\site-packages (from powerlaw) (1.3.0)
Requirement already satisfied: contourpy>=1.0.1 in c:\users\benja\anaconda3\lib\site-packages (from matplotlib->powerlaw) (1.0.5)
Requirement already satisfied: cycler>=0.10 in c:\users\benja\anaconda3\lib\site-packages (from matplotlib->powerlaw) (0.11.0)
Requirement already satisfied: fonttools>=4.22.0 in c:\users\benja\anaconda3\lib\site-packages (from matplotlib->powerlaw) (4.25.0)
Requirement already satisfied: kiwisolver>=1.0.1 in c:\users\benja\anaconda3\lib\site-packages (from matplotlib->powerlaw) (1.4.4)
Requirement already satisfied: packaging>=20.0 in c:\users\benja\anaconda3\lib\site-packages (from matplotlib->powerlaw) (23.0)
Requirement already satisfied: pillow>=6.2.0 in c:\users\benja\anaconda3\lib\site-packages (from matplotlib->powerlaw) (9.4.0)
Requirement already satisfied: pyparsing>=2.3.1 in c:\users\benja\anaconda3\lib\site-packages (from matplotlib->powerlaw) (3.0.9)
Requirement already satisfied: python-dateutil>=2.7 in c:\users\benja\anaconda3\lib\site-packages (from matplotlib->powerlaw) (2.8.2)
Requirement already satisfied: six>=1.5 in c:\users\benja\anaconda3\lib\site-packages (from python-dateutil>=2.7->matplotlib->powerlaw) (1.16.0)
Downloading powerlaw-1.5-py3-none-any.whl (24 kB)
Installing collected packages: powerlaw
Successfully installed powerlaw-1.5
In [22]:
import networkx as nx
import powerlaw
import pandas as pd
import matplotlib.pyplot as plt

# 1) Carga el grafo dirigido y lo convierte a no dirigido para extraer la componente gigante
G_air = read_dir_graph_weighted('airport.txt')
G_air_und = G_air.to_undirected()
comp = max(nx.connected_components(G_air_und), key=len)
Gg_air = G_air_und.subgraph(comp).copy()

# 2) Calcula parámetros observados
n = Gg_air.number_of_nodes()
m = Gg_air.number_of_edges()
grado_medio_obs = 2 * m / n
m0 = int(round(grado_medio_obs / (2 - 1/n)))  # m₀ para BA

# 3) Simulaciones de los tres modelos
repetitions = 100
data = []

for seed in range(repetitions):
    d = {}

    # — Barabasi–Albert —
    G = nx.barabasi_albert_graph(n, m0, seed=seed)
    d['ba_avg_clus']   = nx.average_clustering(G)
    d['ba_avg_dist']   = nx.average_shortest_path_length(G)
    d['ba_avg_degree'] = 2 * G.number_of_edges() / n
    d['ba_alpha']      = powerlaw.Fit(
                            [deg for _, deg in G.degree()],
                            discrete=True,
                            xmin=8
                         ).alpha

    # — Erdos–Rényi —
    G = nx.gnm_random_graph(n, m, seed=seed)
    d['er_avg_clus']   = nx.average_clustering(G)
    d['er_avg_dist']   = nx.average_shortest_path_length(G)
    d['er_avg_degree'] = 2 * G.number_of_edges() / n

    # — Watts–Strogatz —
    k = int(round(grado_medio_obs))
    G = nx.watts_strogatz_graph(n, k, 0.03, seed=seed)
    d['ws_avg_clus']   = nx.average_clustering(G)
    d['ws_avg_dist']   = nx.average_shortest_path_length(G)
    d['ws_avg_degree'] = 2 * G.number_of_edges() / n

    data.append(d)

df = pd.DataFrame(data)

# 4) Valores reales de la componente gigante
valores_reales = {
    'avg_clus':  nx.average_clustering(Gg_air),
    'avg_dist':  nx.average_shortest_path_length(Gg_air),
    'avg_degree': grado_medio_obs
}

# 5) Gráficos 3×3 comparando distribuciones y valor observado
fig, axs = plt.subplots(3, 3, figsize=(15, 12))
indicadores = ['avg_clus', 'avg_dist', 'avg_degree']
modelos     = ['ba', 'er', 'ws']

for i, ind in enumerate(indicadores):
    for j, model in enumerate(modelos):
        ax = axs[i, j]
        col = f'{model}_{ind}'
        df[col].hist(ax=ax, density=True, bins=30)
        ax.axvline(valores_reales[ind], color='r', linewidth=2)
        ax.set_title(f'{model.upper()} – {ind}')

plt.tight_layout()
plt.show()
In [27]:
df = pd.DataFrame(data)
plt.plot(df['ba_avg_dist'].values,df['ba_avg_clus'].values,'ro',label='BA')
plt.plot(df['er_avg_dist'].values,df['er_avg_clus'].values,'bo',label='ER')
plt.plot(df['ws_avg_dist'].values,df['ws_avg_clus'].values,'go',label='WS')
plt.plot(nx.average_shortest_path_length(Gg_air),nx.average_clustering(Gg_air),'ko',label='air')

plt.legend()
plt.ylabel('Clustering medio')
plt.xlabel('Minimo camino medio')

plt.show()
In [29]:
import networkx as nx
import powerlaw
import pandas as pd
import matplotlib.pyplot as plt
import urllib.request



# 2) Carga y componente gigante
G_ce = read_graph_weighted("celegans.txt")
G_ce_und = G_ce.to_undirected()
comp = max(nx.connected_components(G_ce_und), key=len)
Gg_ce = G_ce_und.subgraph(comp).copy()

# 3) Parámetros observados
n = Gg_ce.number_of_nodes()
m = Gg_ce.number_of_edges()
grado_medio_obs = 2 * m / n
m0 = int(round(grado_medio_obs / (2 - 1/n)))  # para BA

print(f"C. elegans: n={n}, m={m}, ⟨k⟩={grado_medio_obs:.2f}, m0={m0}")

# 4) Simulaciones
repetitions = 50   # <–– baja de 100 a 50 para ganar velocidad
data = []

for seed in range(repetitions):
    d = {}
    # — Barabasi–Albert
    G = nx.barabasi_albert_graph(n, m0, seed=seed)
    d['ba_avg_clus']   = nx.average_clustering(G)
    d['ba_avg_dist']   = nx.average_shortest_path_length(G)
    d['ba_avg_degree'] = 2 * G.number_of_edges() / n
    # alpha solo en BA
    degs = [deg for _, deg in G.degree()]
    d['ba_alpha']      = powerlaw.Fit(degs, discrete=True, xmin=2).alpha

    # — Erdos–Rényi
    G = nx.gnm_random_graph(n, m, seed=seed)
    d['er_avg_clus']   = nx.average_clustering(G)
    d['er_avg_dist']   = nx.average_shortest_path_length(G)
    d['er_avg_degree'] = 2 * G.number_of_edges() / n

    # — Watts–Strogatz
    k = int(round(grado_medio_obs))
    G = nx.watts_strogatz_graph(n, k, 0.03, seed=seed)
    d['ws_avg_clus']   = nx.average_clustering(G)
    d['ws_avg_dist']   = nx.average_shortest_path_length(G)
    d['ws_avg_degree'] = 2 * G.number_of_edges() / n

    data.append(d)

df = pd.DataFrame(data)

# 5) Valores reales
valores_reales = {
    'avg_clus':  nx.average_clustering(Gg_ce),
    'avg_dist':  nx.average_shortest_path_length(Gg_ce),
    'avg_degree': grado_medio_obs
}

# 6) Gráficos 3×3
fig, axs = plt.subplots(3, 3, figsize=(15, 12))
indicadores = ['avg_clus', 'avg_dist', 'avg_degree']
modelos     = ['ba', 'er', 'ws']

for i, ind in enumerate(indicadores):
    for j, model in enumerate(modelos):
        ax = axs[i, j]
        col = f'{model}_{ind}'
        df[col].hist(ax=ax, density=True, bins=25)
        ax.axvline(valores_reales[ind], color='r', lw=2)
        ax.set_title(f'{model.upper()} – {ind}')
plt.tight_layout()

# 7) Scatter clustering vs. dist
fig2, ax2 = plt.subplots(figsize=(6, 5))
ax2.plot(df['ba_avg_dist'], df['ba_avg_clus'], 'ro', label='BA')
ax2.plot(df['er_avg_dist'], df['er_avg_clus'], 'bo', label='ER')
ax2.plot(df['ws_avg_dist'], df['ws_avg_clus'], 'go', label='WS')
ax2.plot(valores_reales['avg_dist'], valores_reales['avg_clus'], 'ko', label='obs')
ax2.set_xlabel('Camino medio')
ax2.set_ylabel('Clustering medio')
ax2.legend()
plt.show()
C. elegans: n=297, m=2148, ⟨k⟩=14.46, m0=7
In [30]:
import networkx as nx
import matplotlib.pyplot as plt
import pickle

def plot_centrality(G, pos, centrality, title, cmap=plt.cm.plasma):
    """
    Dibuja G usando 'pos', coloreando y escalando nodos según 'centrality'.
    """
    vals = list(centrality.values())
    # normalizar colores entre 0 y 1
    norm = [(v - min(vals)) / (max(vals) - min(vals) + 1e-6) for v in vals]
    # escalas de tamaño (entre 100 y 1000)
    sizes = [100 + 900 * x for x in norm]
    nx.draw_networkx_nodes(G, pos,
                           node_size=sizes,
                           node_color=vals,
                           cmap=cmap)
    nx.draw_networkx_edges(G, pos, alpha=0.3)
    plt.title(title)
    plt.axis('off')

# --- 1) Grafo dirigido: Airport (componente fuertemente conexa) ---
G_air = read_dir_graph_weighted('airport.txt')
H_air = obtener_mayor_componente_fuertemente_conexa(G_air)
with open('airportStronglyConn_pos.pkl','rb') as f:
    pos_air = pickle.load(f)

# Centralidades
deg_air = nx.degree_centrality(H_air)    # grado (in+out normalizado)
pr_air  = nx.pagerank(H_air, weight='weight')

plt.figure(figsize=(12,5))
plt.subplot(1,2,1)
plot_centrality(H_air, pos_air, deg_air, "Airport: Degree Centrality")
plt.subplot(1,2,2)
plot_centrality(H_air, pos_air, pr_air,  "Airport: PageRank")
plt.show()

# --- 2) Grafo no dirigido: C. elegans ---
G_ce = read_graph_weighted('celegans.txt')
pos_ce = nx.spring_layout(G_ce, iterations=1000, seed=42)

# Centralidades
deg_ce = nx.degree_centrality(G_ce)
btw_ce = nx.betweenness_centrality(G_ce, weight='weight', normalized=True)

plt.figure(figsize=(12,5))
plt.subplot(1,2,1)
plot_centrality(G_ce, pos_ce, deg_ce, "C. elegans: Degree Centrality")
plt.subplot(1,2,2)
plot_centrality(G_ce, pos_ce, btw_ce, "C. elegans: Betweenness")
plt.show()
In [33]:
import networkx as nx
import pandas as pd

# 1) Carga y extrae componente gigante
G_air = read_dir_graph_weighted('airport.txt')
G_air_und = G_air.to_undirected()
comp = max(nx.connected_components(G_air_und), key=len)

# Grafo para degree-centrality (no dirigido)
Gg_und = G_air_und.subgraph(comp).copy()
# Grafo para pagerank (dirigido, restringido a la misma compon.)
Gg_dir = G_air.subgraph(comp).copy()

# 2) Calcula centralidades
deg_cent = nx.degree_centrality(Gg_und)
pr      = nx.pagerank(Gg_dir, alpha=0.85)

# 3) Monta DataFrame y ordena por degree centrality
df = pd.DataFrame([
    {'airport': n, 
     'degree_centrality': deg_cent[n], 
     'pagerank': pr.get(n, 0)}
    for n in Gg_und.nodes()
])
df = df.sort_values('degree_centrality', ascending=False).reset_index(drop=True)

# 4) Imprime el resultado
print(df.to_string(index=False, float_format='%.4f'))
 airport  degree_centrality  pagerank
      45             0.1999    0.0366
      68             0.1903    0.0105
      87             0.1884    0.0281
     164             0.1859    0.0256
      73             0.1852    0.0225
     146             0.1744    0.0240
     149             0.1738    0.0150
     173             0.1712    0.0161
     158             0.1700    0.0179
     316             0.1661    0.0168
      56             0.1617    0.0229
      59             0.1604    0.0137
     132             0.1560    0.0122
      89             0.1553    0.0125
     163             0.1528    0.0164
      79             0.1470    0.0142
     135             0.1394    0.0033
     195             0.1362    0.0169
      61             0.1343    0.0096
       9             0.1305    0.0043
      50             0.1299    0.0035
      53             0.1292    0.0039
     136             0.1286    0.0087
     105             0.1260    0.0048
      54             0.1248    0.0150
      82             0.1241    0.0042
      91             0.1241    0.0031
     194             0.1229    0.0225
     176             0.1229    0.0019
     182             0.1209    0.0162
      81             0.1203    0.0048
     187             0.1203    0.0035
     145             0.1190    0.0070
      76             0.1190    0.0094
      71             0.1171    0.0031
      78             0.1171    0.0042
     112             0.1165    0.0099
     101             0.1146    0.0051
     137             0.1146    0.0024
     174             0.1120    0.0033
     127             0.1120    0.0034
     193             0.1101    0.0015
      80             0.1101    0.0065
      31             0.1095    0.0222
     190             0.1076    0.0030
      48             0.1057    0.0012
     177             0.1057    0.0017
     202             0.1050    0.0064
     128             0.1038    0.0021
     142             0.1031    0.0033
     229             0.1012    0.0021
     181             0.0980    0.0071
     102             0.0980    0.0011
     134             0.0974    0.0021
     110             0.0948    0.0004
      58             0.0936    0.0009
      77             0.0936    0.0009
     239             0.0923    0.0008
     124             0.0910    0.0014
     189             0.0910    0.0071
     179             0.0898    0.0013
      94             0.0891    0.0015
     175             0.0885    0.0043
     185             0.0878    0.0016
     196             0.0872    0.0037
     188             0.0866    0.0018
     203             0.0847    0.0015
      69             0.0847    0.0007
     103             0.0840    0.0002
      55             0.0840    0.0011
     123             0.0834    0.0027
      21             0.0834    0.0074
      72             0.0834    0.0021
      84             0.0827    0.0007
     199             0.0815    0.0036
     257             0.0802    0.0010
     464             0.0783    0.0006
     198             0.0783    0.0039
     178             0.0777    0.0022
     107             0.0770    0.0012
     139             0.0770    0.0008
      75             0.0764    0.0006
     273             0.0757    0.0009
     144             0.0751    0.0029
     156             0.0751    0.0034
      51             0.0738    0.0008
     349             0.0732    0.0006
     170             0.0713    0.0011
     180             0.0713    0.0029
      96             0.0707    0.0030
      66             0.0707    0.0006
      67             0.0707    0.0005
     131             0.0700    0.0014
     271             0.0694    0.0007
     258             0.0694    0.0008
     151             0.0687    0.0016
     375             0.0681    0.0005
     270             0.0668    0.0011
     211             0.0662    0.0013
     475             0.0649    0.0005
      83             0.0643    0.0005
      85             0.0643    0.0009
     249             0.0637    0.0007
      64             0.0637    0.0006
     248             0.0637    0.0006
     204             0.0637    0.0022
     272             0.0637    0.0045
     244             0.0630    0.0009
     268             0.0624    0.0008
     353             0.0617    0.0005
      43             0.0617    0.0004
      65             0.0617    0.0004
     571             0.0605    0.0008
     201             0.0598    0.0004
     618             0.0598    0.0005
      52             0.0592    0.0006
     417             0.0592    0.0095
     256             0.0554    0.0004
      70             0.0547    0.0004
      97             0.0535    0.0013
     396             0.0528    0.0067
      62             0.0528    0.0005
     184             0.0528    0.0007
     235             0.0516    0.0002
      46             0.0509    0.0003
      95             0.0490    0.0004
     165             0.0484    0.0005
      57             0.0484    0.0003
     160             0.0477    0.0008
     205             0.0477    0.0011
     470             0.0477    0.0006
      86             0.0477    0.0010
     147             0.0471    0.0003
     313             0.0465    0.0004
     314             0.0465    0.0021
     104             0.0458    0.0004
     150             0.0458    0.0006
     472             0.0458    0.0002
     378             0.0452    0.0004
     157             0.0452    0.0004
     126             0.0446    0.0004
     254             0.0446    0.0004
     252             0.0439    0.0022
     590             0.0439    0.0005
     545             0.0439    0.0002
     108             0.0433    0.0002
     690             0.0426    0.0003
     166             0.0426    0.0014
     462             0.0426    0.0006
     100             0.0420    0.0006
      90             0.0414    0.0006
     338             0.0407    0.0006
     167             0.0407    0.0004
     130             0.0401    0.0007
     355             0.0395    0.0004
     584             0.0388    0.0003
     262             0.0382    0.0004
      30             0.0382    0.0031
     465             0.0382    0.0003
     608             0.0382    0.0002
     539             0.0382    0.0005
     191             0.0382    0.0007
     466             0.0376    0.0002
     168             0.0376    0.0019
     686             0.0376    0.0006
     658             0.0369    0.0003
     245             0.0369    0.0003
     513             0.0350    0.0027
     731             0.0350    0.0004
     337             0.0350    0.0003
     471             0.0350    0.0002
     265             0.0344    0.0003
     676             0.0344    0.0002
     725             0.0344    0.0003
     596             0.0344    0.0005
     694             0.0337    0.0003
     612             0.0325    0.0003
     344             0.0325    0.0002
     255             0.0325    0.0003
      47             0.0325    0.0002
     197             0.0318    0.0008
     140             0.0318    0.0004
     183             0.0318    0.0004
     461             0.0318    0.0003
     507             0.0312    0.0007
     328             0.0312    0.0005
     251             0.0312    0.0003
     153             0.0312    0.0006
      26             0.0306    0.0006
     720             0.0306    0.0002
     463             0.0306    0.0002
     372             0.0299    0.0003
     275             0.0299    0.0003
     289             0.0299    0.0013
     575             0.0293    0.0004
     657             0.0293    0.0006
     374             0.0293    0.0003
     169             0.0293    0.0004
     186             0.0286    0.0007
     691             0.0280    0.0002
      13             0.0280    0.0024
     371             0.0274    0.0003
     664             0.0274    0.0006
     264             0.0274    0.0009
     534             0.0274    0.0006
     512             0.0267    0.0026
     148             0.0267    0.0004
      60             0.0261    0.0002
     219             0.0261    0.0002
     274             0.0261    0.0002
     253             0.0261    0.0002
     468             0.0255    0.0002
     632             0.0255    0.0050
       1             0.0255    0.0029
     619             0.0255    0.0008
      16             0.0248    0.0016
     960             0.0248    0.0033
     413             0.0248    0.0004
     172             0.0242    0.0003
     373             0.0236    0.0043
     936             0.0236    0.0002
     672             0.0236    0.0007
     839             0.0236    0.0002
     152             0.0236    0.0004
     425             0.0236    0.0008
     649             0.0229    0.0004
     496             0.0229    0.0026
     129             0.0229    0.0002
     403             0.0229    0.0003
     340             0.0229    0.0001
     662             0.0223    0.0001
     171             0.0223    0.0002
     398             0.0223    0.0006
      98             0.0223    0.0008
     312             0.0223    0.0004
     707             0.0223    0.0002
     277             0.0216    0.0002
     607             0.0216    0.0004
      63             0.0216    0.0004
      22             0.0210    0.0004
     550             0.0210    0.0004
     154             0.0210    0.0002
     402             0.0210    0.0004
     407             0.0210    0.0003
     610             0.0210    0.0003
     976             0.0204    0.0052
     975             0.0204    0.0031
     505             0.0204    0.0004
     230             0.0197    0.0007
     702             0.0197    0.0002
     841             0.0197    0.0002
     362             0.0191    0.0005
     730             0.0191    0.0004
     341             0.0191    0.0001
     799             0.0191    0.0001
     732             0.0191    0.0003
     846             0.0191    0.0002
     345             0.0185    0.0005
     593             0.0185    0.0023
     574             0.0185    0.0004
     159             0.0185    0.0002
     708             0.0185    0.0001
     583             0.0185    0.0001
     220             0.0185    0.0003
     719             0.0185    0.0002
     365             0.0178    0.0030
     705             0.0178    0.0001
     400             0.0178    0.0002
     122             0.0178    0.0003
      92             0.0178    0.0003
     276             0.0178    0.0002
     601             0.0178    0.0002
       4             0.0172    0.0018
      93             0.0172    0.0001
     630             0.0172    0.0003
     703             0.0172    0.0002
     597             0.0172    0.0002
     484             0.0172    0.0018
     215             0.0172    0.0017
     957             0.0172    0.0047
     806             0.0172    0.0009
     405             0.0172    0.0003
     401             0.0172    0.0003
     685             0.0172    0.0002
     399             0.0172    0.0002
     408             0.0165    0.0002
     520             0.0165    0.0002
     162             0.0165    0.0002
     798             0.0165    0.0002
     232             0.0165    0.0002
     700             0.0165    0.0003
     333             0.0165    0.0002
     656             0.0165    0.0001
     674             0.0165    0.0001
     430             0.0159    0.0003
     354             0.0159    0.0009
     361             0.0159    0.0002
     391             0.0159    0.0003
     677             0.0159    0.0004
     410             0.0159    0.0003
     826             0.0159    0.0003
     892             0.0159    0.0012
     234             0.0159    0.0002
     578             0.0159    0.0005
     699             0.0153    0.0003
     847             0.0153    0.0002
     609             0.0153    0.0002
     580             0.0153    0.0003
     689             0.0153    0.0002
     241             0.0153    0.0006
     735             0.0153    0.0004
     309             0.0153    0.0002
     404             0.0153    0.0002
     701             0.0153    0.0003
     624             0.0153    0.0002
     673             0.0153    0.0003
     500             0.0146    0.0002
     503             0.0146    0.0014
     348             0.0146    0.0002
     113             0.0146    0.0002
     587             0.0146    0.0005
     819             0.0146    0.0002
     756             0.0146    0.0003
     233             0.0146    0.0001
     409             0.0146    0.0003
     228             0.0146    0.0003
     397             0.0146    0.0003
     335             0.0146    0.0002
      99             0.0146    0.0002
     754             0.0140    0.0003
     790             0.0140    0.0002
     329             0.0140    0.0002
     263             0.0140    0.0002
     751             0.0140    0.0002
     351             0.0140    0.0006
     502             0.0140    0.0003
     326             0.0140    0.0002
     549             0.0134    0.0002
     119             0.0134    0.0003
     380             0.0134    0.0001
     757             0.0134    0.0002
      20             0.0134    0.0011
     352             0.0134    0.0003
     395             0.0134    0.0002
     347             0.0134    0.0005
     414             0.0134    0.0002
     620             0.0134    0.0002
     480             0.0134    0.0002
     406             0.0134    0.0002
     412             0.0134    0.0002
     459             0.0134    0.0003
     212             0.0134    0.0001
     645             0.0134    0.0002
     237             0.0127    0.0001
     529             0.0127    0.0003
     415             0.0127    0.0003
    1033             0.0127    0.0002
     650             0.0127    0.0008
     827             0.0127    0.0003
     336             0.0127    0.0002
     759             0.0127    0.0002
     688             0.0127    0.0002
     325             0.0127    0.0002
     634             0.0127    0.0002
     278             0.0127    0.0002
     525             0.0121    0.0002
     331             0.0121    0.0002
     832             0.0121    0.0014
     746             0.0121    0.0006
     748             0.0121    0.0001
     648             0.0121    0.0002
     383             0.0121    0.0001
     670             0.0121    0.0003
     238             0.0121    0.0001
     305             0.0121    0.0002
     783             0.0121    0.0004
     626             0.0121    0.0009
     882             0.0121    0.0002
     617             0.0121    0.0002
     871             0.0121    0.0002
     568             0.0121    0.0004
     716             0.0121    0.0002
     115             0.0121    0.0002
      32             0.0121    0.0002
     842             0.0121    0.0001
      88             0.0121    0.0002
     225             0.0115    0.0003
     613             0.0115    0.0009
     515             0.0115    0.0001
     655             0.0115    0.0006
     627             0.0115    0.0019
     236             0.0115    0.0001
      49             0.0115    0.0005
     427             0.0115    0.0002
     421             0.0115    0.0002
     222             0.0115    0.0004
     559             0.0115    0.0001
     292             0.0115    0.0008
     639             0.0115    0.0009
     853             0.0115    0.0006
     592             0.0115    0.0005
     367             0.0115    0.0007
     589             0.0115    0.0002
      14             0.0108    0.0003
     581             0.0108    0.0003
     524             0.0108    0.0002
     431             0.0108    0.0002
     526             0.0108    0.0002
     411             0.0108    0.0002
     640             0.0108    0.0006
     487             0.0108    0.0002
     106             0.0108    0.0002
     663             0.0108    0.0007
     116             0.0108    0.0002
     516             0.0108    0.0006
     504             0.0108    0.0002
     121             0.0108    0.0002
     791             0.0108    0.0001
     727             0.0108    0.0002
     473             0.0108    0.0001
     579             0.0108    0.0003
     810             0.0108    0.0001
     733             0.0108    0.0002
    1026             0.0108    0.0001
     712             0.0108    0.0002
     711             0.0108    0.0002
     894             0.0102    0.0011
     965             0.0102    0.0001
     901             0.0102    0.0001
     622             0.0102    0.0010
     226             0.0102    0.0005
     633             0.0102    0.0006
     605             0.0102    0.0004
     433             0.0102    0.0002
     669             0.0102    0.0004
     973             0.0102    0.0002
     192             0.0102    0.0002
    1098             0.0095    0.0002
     332             0.0095    0.0001
     424             0.0095    0.0001
     243             0.0095    0.0002
     426             0.0095    0.0002
     339             0.0095    0.0006
     117             0.0095    0.0002
     718             0.0095    0.0001
     850             0.0095    0.0001
     671             0.0095    0.0001
     322             0.0095    0.0007
    1068             0.0095    0.0002
      34             0.0095    0.0002
     291             0.0095    0.0007
     582             0.0089    0.0002
     577             0.0089    0.0002
     495             0.0089    0.0002
     536             0.0089    0.0002
     267             0.0089    0.0001
     455             0.0089    0.0002
     681             0.0089    0.0002
     324             0.0089    0.0002
     714             0.0089    0.0001
     809             0.0089    0.0001
     246             0.0089    0.0003
     825             0.0089    0.0002
     838             0.0089    0.0001
     861             0.0089    0.0005
     896             0.0089    0.0001
     120             0.0089    0.0003
     114             0.0089    0.0002
     111             0.0089    0.0001
     898             0.0089    0.0002
      42             0.0089    0.0007
     906             0.0089    0.0002
     961             0.0089    0.0002
    1097             0.0089    0.0002
    1110             0.0089    0.0001
     334             0.0089    0.0002
     224             0.0089    0.0006
     621             0.0089    0.0004
     377             0.0089    0.0001
     631             0.0089    0.0007
     118             0.0083    0.0002
     508             0.0083    0.0002
     432             0.0083    0.0001
      44             0.0083    0.0001
     438             0.0083    0.0002
      33             0.0083    0.0001
     652             0.0083    0.0002
     223             0.0083    0.0001
     556             0.0083    0.0002
     240             0.0083    0.0002
     389             0.0083    0.0002
     434             0.0083    0.0002
     604             0.0083    0.0006
     293             0.0083    0.0002
     294             0.0083    0.0002
     379             0.0083    0.0001
     260             0.0083    0.0001
     547             0.0083    0.0002
     918             0.0076    0.0001
     435             0.0076    0.0002
    1105             0.0076    0.0001
    1190             0.0076    0.0003
     920             0.0076    0.0015
       7             0.0076    0.0012
    1006             0.0076    0.0008
    1102             0.0076    0.0002
     448             0.0076    0.0002
     565             0.0076    0.0002
     675             0.0076    0.0003
     356             0.0076    0.0002
     848             0.0076    0.0002
     697             0.0076    0.0001
     773             0.0076    0.0019
     387             0.0076    0.0002
     429             0.0076    0.0001
     453             0.0076    0.0001
     611             0.0076    0.0006
     501             0.0076    0.0009
     651             0.0076    0.0003
     533             0.0076    0.0012
     852             0.0070    0.0002
     570             0.0070    0.0003
     660             0.0070    0.0004
    1016             0.0070    0.0001
     857             0.0070    0.0002
     569             0.0070    0.0002
     747             0.0070    0.0002
     745             0.0070    0.0016
     667             0.0070    0.0004
    1104             0.0070    0.0001
     603             0.0070    0.0002
     646             0.0070    0.0006
    1121             0.0070    0.0001
     925             0.0070    0.0001
     786             0.0070    0.0001
     510             0.0070    0.0002
     390             0.0070    0.0002
     321             0.0070    0.0003
     444             0.0070    0.0001
     213             0.0070    0.0001
     392             0.0070    0.0002
     776             0.0064    0.0003
     769             0.0064    0.0001
     419             0.0064    0.0006
     519             0.0064    0.0002
     792             0.0064    0.0001
     303             0.0064    0.0002
     350             0.0064    0.0003
     692             0.0064    0.0001
     514             0.0064    0.0002
     706             0.0064    0.0001
     320             0.0064    0.0002
     330             0.0064    0.0001
     599             0.0064    0.0002
     553             0.0064    0.0002
     643             0.0064    0.0003
     954             0.0064    0.0007
     951             0.0064    0.0013
     962             0.0064    0.0001
     966             0.0064    0.0001
    1176             0.0064    0.0002
     436             0.0064    0.0003
     623             0.0064    0.0001
    1030             0.0064    0.0001
     454             0.0057    0.0001
     388             0.0057    0.0002
     661             0.0057    0.0002
     682             0.0057    0.0002
     477             0.0057    0.0001
     606             0.0057    0.0006
     625             0.0057    0.0002
       2             0.0057    0.0003
     428             0.0057    0.0001
     637             0.0057    0.0001
    1100             0.0057    0.0002
     535             0.0057    0.0001
     318             0.0057    0.0002
    1357             0.0057    0.0001
     948             0.0057    0.0001
     937             0.0057    0.0001
     972             0.0057    0.0001
     109             0.0057    0.0001
    1241             0.0057    0.0004
     863             0.0057    0.0001
     824             0.0057    0.0002
     817             0.0057    0.0001
     259             0.0057    0.0001
     266             0.0057    0.0001
     777             0.0057    0.0009
     282             0.0057    0.0001
     767             0.0057    0.0001
     296             0.0057    0.0002
    1207             0.0057    0.0002
     739             0.0057    0.0001
     738             0.0057    0.0004
    1075             0.0057    0.0004
     598             0.0057    0.0004
     729             0.0057    0.0001
      36             0.0057    0.0001
     511             0.0057    0.0001
    1157             0.0057    0.0003
    1145             0.0057    0.0001
     522             0.0057    0.0001
    1159             0.0057    0.0002
    1320             0.0051    0.0001
    1267             0.0051    0.0003
     327             0.0051    0.0001
      74             0.0051    0.0001
     509             0.0051    0.0005
     638             0.0051    0.0002
     812             0.0051    0.0001
     247             0.0051    0.0001
     909             0.0051    0.0002
     680             0.0051    0.0003
    1106             0.0051    0.0001
     370             0.0051    0.0001
    1010             0.0051    0.0001
    1099             0.0051    0.0001
     214             0.0051    0.0002
    1310             0.0051    0.0002
     385             0.0051    0.0001
    1254             0.0051    0.0002
     544             0.0051    0.0001
     977             0.0051    0.0025
     996             0.0051    0.0002
    1407             0.0051    0.0001
     133             0.0051    0.0001
      35             0.0051    0.0001
    1258             0.0051    0.0002
     567             0.0051    0.0001
     285             0.0051    0.0001
     836             0.0051    0.0001
    1317             0.0051    0.0001
     287             0.0051    0.0003
     835             0.0051    0.0001
     876             0.0051    0.0002
    1058             0.0045    0.0001
    1138             0.0045    0.0001
     734             0.0045    0.0001
     913             0.0045    0.0001
    1042             0.0045    0.0002
    1046             0.0045    0.0001
     758             0.0045    0.0001
     710             0.0045    0.0001
     855             0.0045    0.0002
    1339             0.0045    0.0002
     868             0.0045    0.0001
     728             0.0045    0.0001
    1298             0.0045    0.0006
    1133             0.0045    0.0001
     865             0.0045    0.0001
     715             0.0045    0.0001
     704             0.0045    0.0001
     386             0.0045    0.0001
     770             0.0045    0.0006
     709             0.0045    0.0001
     917             0.0045    0.0002
    1060             0.0045    0.0002
     815             0.0045    0.0001
     828             0.0045    0.0002
    1177             0.0045    0.0002
     446             0.0045    0.0001
     250             0.0045    0.0001
     628             0.0045    0.0003
     523             0.0045    0.0001
     615             0.0045    0.0002
    1117             0.0045    0.0002
      29             0.0045    0.0001
    1414             0.0045    0.0003
     476             0.0045    0.0001
     813             0.0045    0.0001
     924             0.0045    0.0001
    1039             0.0045    0.0001
     814             0.0045    0.0001
    1122             0.0045    0.0002
     242             0.0038    0.0001
     449             0.0038    0.0002
     527             0.0038    0.0001
     897             0.0038    0.0001
     659             0.0038    0.0001
    1439             0.0038    0.0001
     558             0.0038    0.0001
     552             0.0038    0.0001
    1085             0.0038    0.0002
     304             0.0038    0.0002
     721             0.0038    0.0001
     763             0.0038    0.0001
    1398             0.0038    0.0001
    1027             0.0038    0.0001
     760             0.0038    0.0001
     955             0.0038    0.0002
    1203             0.0038    0.0001
    1004             0.0038    0.0002
     482             0.0038    0.0003
    1421             0.0038    0.0003
     899             0.0038    0.0001
     678             0.0038    0.0007
     494             0.0038    0.0001
     381             0.0038    0.0001
     269             0.0038    0.0001
    1024             0.0038    0.0001
       6             0.0038    0.0002
      18             0.0038    0.0003
     980             0.0038    0.0001
    1182             0.0038    0.0006
     423             0.0038    0.0002
     506             0.0038    0.0001
     210             0.0038    0.0001
     585             0.0038    0.0003
     346             0.0038    0.0003
     971             0.0038    0.0003
     687             0.0038    0.0001
    1132             0.0038    0.0002
    1213             0.0038    0.0002
     854             0.0038    0.0001
     161             0.0038    0.0001
    1011             0.0032    0.0001
     830             0.0032    0.0010
    1044             0.0032    0.0001
     753             0.0032    0.0002
     283             0.0032    0.0001
     209             0.0032    0.0001
     829             0.0032    0.0001
    1347             0.0032    0.0002
     870             0.0032    0.0002
     796             0.0032    0.0001
    1038             0.0032    0.0001
    1017             0.0032    0.0001
     554             0.0032    0.0001
     789             0.0032    0.0001
     859             0.0032    0.0001
     771             0.0032    0.0003
    1032             0.0032    0.0001
     811             0.0032    0.0001
    1050             0.0032    0.0002
    1029             0.0032    0.0001
     768             0.0032    0.0001
     823             0.0032    0.0001
    1396             0.0032    0.0001
     808             0.0032    0.0001
     548             0.0032    0.0001
    1012             0.0032    0.0003
     231             0.0032    0.0001
     866             0.0032    0.0001
     816             0.0032    0.0001
    1055             0.0032    0.0001
    1028             0.0032    0.0001
     644             0.0032    0.0001
     939             0.0032    0.0001
     990             0.0032    0.0001
     343             0.0032    0.0001
     586             0.0032    0.0001
    1362             0.0032    0.0004
     905             0.0032    0.0001
     445             0.0032    0.0001
    1179             0.0032    0.0001
     359             0.0032    0.0001
     910             0.0032    0.0001
    1249             0.0032    0.0007
     967             0.0032    0.0001
    1103             0.0032    0.0001
     635             0.0032    0.0001
    1096             0.0032    0.0002
     912             0.0032    0.0001
     922             0.0032    0.0001
     368             0.0032    0.0001
     915             0.0032    0.0001
     382             0.0032    0.0001
     499             0.0032    0.0005
    1493             0.0032    0.0001
     498             0.0032    0.0001
     696             0.0032    0.0001
    1090             0.0032    0.0001
    1239             0.0032    0.0002
     930             0.0032    0.0001
    1302             0.0032    0.0001
    1162             0.0032    0.0001
    1067             0.0032    0.0002
     741             0.0032    0.0002
    1005             0.0032    0.0001
     602             0.0032    0.0003
     647             0.0032    0.0001
     537             0.0032    0.0002
     952             0.0032    0.0002
     884             0.0032    0.0001
     978             0.0032    0.0002
     963             0.0032    0.0001
     531             0.0032    0.0001
    1107             0.0032    0.0002
     722             0.0032    0.0001
     891             0.0032    0.0001
    1083             0.0032    0.0001
     717             0.0032    0.0001
     315             0.0032    0.0001
     994             0.0032    0.0003
     944             0.0032    0.0001
    1255             0.0025    0.0001
     934             0.0025    0.0001
    1303             0.0025    0.0001
    1147             0.0025    0.0004
    1158             0.0025    0.0001
     942             0.0025    0.0001
     945             0.0025    0.0001
     947             0.0025    0.0001
     538             0.0025    0.0002
     956             0.0025    0.0012
     964             0.0025    0.0001
     208             0.0025    0.0001
    1025             0.0025    0.0001
      19             0.0025    0.0001
     879             0.0025    0.0001
    1001             0.0025    0.0003
     141             0.0025    0.0001
    1305             0.0025    0.0001
     885             0.0025    0.0001
    1240             0.0025    0.0002
     867             0.0025    0.0001
    1242             0.0025    0.0001
     993             0.0025    0.0001
     992             0.0025    0.0002
    1226             0.0025    0.0001
     543             0.0025    0.0002
     856             0.0025    0.0001
    1247             0.0025    0.0001
     206             0.0025    0.0001
    1225             0.0025    0.0001
    1309             0.0025    0.0001
     872             0.0025    0.0001
     927             0.0025    0.0003
     928             0.0025    0.0001
    1219             0.0025    0.0003
     532             0.0025    0.0001
     138             0.0025    0.0001
    1411             0.0025    0.0001
     218             0.0025    0.0002
    1166             0.0025    0.0001
     376             0.0025    0.0001
    1531             0.0025    0.0001
     366             0.0025    0.0001
     364             0.0025    0.0001
     683             0.0025    0.0001
     360             0.0025    0.0001
     358             0.0025    0.0001
    1184             0.0025    0.0002
     695             0.0025    0.0001
     572             0.0025    0.0002
    1072             0.0025    0.0001
    1318             0.0025    0.0001
     317             0.0025    0.0002
    1192             0.0025    0.0001
    1084             0.0025    0.0001
    1081             0.0025    0.0001
    1080             0.0025    0.0002
     302             0.0025    0.0001
     566             0.0025    0.0001
    1078             0.0025    0.0001
     666             0.0025    0.0001
     497             0.0025    0.0002
     394             0.0025    0.0001
     416             0.0025    0.0003
     485             0.0025    0.0001
     595             0.0025    0.0001
     594             0.0025    0.0001
     474             0.0025    0.0001
     456             0.0025    0.0001
     452             0.0025    0.0001
    1422             0.0025    0.0002
     591             0.0025    0.0002
     489             0.0025    0.0001
     447             0.0025    0.0005
     629             0.0025    0.0003
    1109             0.0025    0.0003
    1429             0.0025    0.0002
     642             0.0025    0.0001
     491             0.0025    0.0001
     420             0.0025    0.0001
    1372             0.0025    0.0003
     654             0.0025    0.0001
    1430             0.0025    0.0001
    1073             0.0025    0.0001
    1137             0.0025    0.0001
    1036             0.0025    0.0001
     755             0.0025    0.0001
     780             0.0025    0.0001
     563             0.0025    0.0001
    1161             0.0025    0.0001
    1342             0.0025    0.0002
     774             0.0025    0.0003
     772             0.0025    0.0003
     766             0.0025    0.0001
    1040             0.0025    0.0001
     765             0.0025    0.0001
     764             0.0025    0.0001
    1344             0.0025    0.0001
    1056             0.0025    0.0001
     805             0.0025    0.0002
    1048             0.0025    0.0001
     227             0.0025    0.0001
    1065             0.0025    0.0001
     221             0.0025    0.0001
     562             0.0025    0.0001
    1209             0.0025    0.0002
     560             0.0025    0.0001
     958             0.0025    0.0003
    1116             0.0019    0.0001
    1256             0.0019    0.0001
    1108             0.0019    0.0003
      17             0.0019    0.0001
    1123             0.0019    0.0002
     969             0.0019    0.0001
    1045             0.0019    0.0001
    1047             0.0019    0.0001
    1222             0.0019    0.0002
    1128             0.0019    0.0001
    1112             0.0019    0.0001
    1043             0.0019    0.0001
    1181             0.0019    0.0002
    1118             0.0019    0.0001
    1172             0.0019    0.0003
    1160             0.0019    0.0001
    1037             0.0019    0.0001
    1120             0.0019    0.0001
    1170             0.0019    0.0001
    1035             0.0019    0.0001
    1144             0.0019    0.0001
    1174             0.0019    0.0001
    1034             0.0019    0.0001
    1071             0.0019    0.0001
     979             0.0019    0.0001
    1216             0.0019    0.0001
     991             0.0019    0.0001
    1000             0.0019    0.0002
    1200             0.0019    0.0001
    1518             0.0019    0.0001
    1007             0.0019    0.0001
    1079             0.0019    0.0001
    1208             0.0019    0.0001
    1520             0.0019    0.0001
    1212             0.0019    0.0001
    1186             0.0019    0.0001
    1057             0.0019    0.0001
    1164             0.0019    0.0001
    1092             0.0019    0.0001
     988             0.0019    0.0001
    1019             0.0019    0.0001
    1244             0.0019    0.0003
     985             0.0019    0.0001
    1094             0.0019    0.0001
    1228             0.0019    0.0001
    1141             0.0019    0.0001
     982             0.0019    0.0001
    1250             0.0019    0.0001
    1101             0.0019    0.0001
    1125             0.0019    0.0001
    1053             0.0019    0.0001
    1051             0.0019    0.0001
    1506             0.0019    0.0001
    1063             0.0019    0.0003
     843             0.0019    0.0001
     953             0.0019    0.0001
    1260             0.0019    0.0002
    1358             0.0019    0.0001
     726             0.0019    0.0001
     297             0.0019    0.0001
    1355             0.0019    0.0001
     737             0.0019    0.0002
     740             0.0019    0.0001
     742             0.0019    0.0001
    1354             0.0019    0.0001
    1469             0.0019    0.0001
     288             0.0019    0.0001
     750             0.0019    0.0001
    1470             0.0019    0.0001
     784             0.0019    0.0003
    1447             0.0019    0.0001
     785             0.0019    0.0001
    1476             0.0019    0.0002
     788             0.0019    0.0001
    1330             0.0019    0.0001
     797             0.0019    0.0001
     261             0.0019    0.0001
     803             0.0019    0.0001
     807             0.0019    0.0002
    1316             0.0019    0.0001
    1481             0.0019    0.0001
     207             0.0019    0.0001
    1308             0.0019    0.0001
    1448             0.0019    0.0001
    1359             0.0019    0.0001
    1307             0.0019    0.0002
     478             0.0019    0.0001
     541             0.0019    0.0001
     528             0.0019    0.0001
     551             0.0019    0.0001
    1385             0.0019    0.0001
     561             0.0019    0.0001
    1379             0.0019    0.0004
    1400             0.0019    0.0002
     576             0.0019    0.0001
     493             0.0019    0.0001
     588             0.0019    0.0001
     490             0.0019    0.0007
     479             0.0019    0.0001
    1417             0.0019    0.0002
    1361             0.0019    0.0001
     614             0.0019    0.0001
    1376             0.0019    0.0004
     442             0.0019    0.0001
    1427             0.0019    0.0001
    1373             0.0019    0.0002
     437             0.0019    0.0005
     422             0.0019    0.0004
     393             0.0019    0.0001
     665             0.0019    0.0001
     384             0.0019    0.0001
     369             0.0019    0.0001
     357             0.0019    0.0001
    1482             0.0019    0.0001
     778             0.0019    0.0001
     860             0.0019    0.0001
     125             0.0019    0.0001
    1300             0.0019    0.0001
    1490             0.0019    0.0001
     932             0.0019    0.0001
     877             0.0019    0.0001
    1273             0.0019    0.0001
     878             0.0019    0.0001
     880             0.0019    0.0001
    1297             0.0019    0.0001
     874             0.0019    0.0001
    1290             0.0019    0.0001
     926             0.0019    0.0001
     923             0.0019    0.0001
     881             0.0019    0.0001
     890             0.0019    0.0001
     883             0.0019    0.0001
    1299             0.0019    0.0001
    1270             0.0019    0.0001
    1271             0.0019    0.0001
     900             0.0019    0.0001
     943             0.0019    0.0001
    1283             0.0019    0.0001
    1306             0.0019    0.0002
     903             0.0019    0.0001
     864             0.0019    0.0001
    1286             0.0019    0.0001
     155             0.0019    0.0001
    1263             0.0019    0.0002
    1264             0.0019    0.0002
    1435             0.0013    0.0001
    1370             0.0013    0.0001
    1288             0.0013    0.0001
    1539             0.0013    0.0007
    1248             0.0013    0.0001
    1375             0.0013    0.0001
    1279             0.0013    0.0001
    1569             0.0013    0.0001
    1281             0.0013    0.0001
    1371             0.0013    0.0002
    1428             0.0013    0.0001
    1280             0.0013    0.0001
    1562             0.0013    0.0001
    1566             0.0013    0.0001
    1425             0.0013    0.0001
    1413             0.0013    0.0001
    1178             0.0013    0.0002
    1423             0.0013    0.0002
    1389             0.0013    0.0001
    1261             0.0013    0.0001
    1388             0.0013    0.0003
    1394             0.0013    0.0001
    1387             0.0013    0.0001
    1382             0.0013    0.0001
    1498             0.0013    0.0002
    1163             0.0013    0.0001
    1269             0.0013    0.0001
    1496             0.0013    0.0001
    1378             0.0013    0.0003
    1153             0.0013    0.0001
    1167             0.0013    0.0001
    1168             0.0013    0.0001
    1169             0.0013    0.0001
    1405             0.0013    0.0001
    1409             0.0013    0.0001
    1377             0.0013    0.0001
    1175             0.0013    0.0001
    1412             0.0013    0.0001
    1274             0.0013    0.0001
    1501             0.0013    0.0001
    1420             0.0013    0.0001
    1503             0.0013    0.0001
    1495             0.0013    0.0001
    1366             0.0013    0.0001
    1444             0.0013    0.0001
    1438             0.0013    0.0001
    1340             0.0013    0.0001
    1475             0.0013    0.0001
    1509             0.0013    0.0001
    1334             0.0013    0.0001
    1479             0.0013    0.0004
    1333             0.0013    0.0001
    1233             0.0013    0.0001
    1329             0.0013    0.0001
    1217             0.0013    0.0001
    1231             0.0013    0.0001
    1328             0.0013    0.0001
    1327             0.0013    0.0001
    1326             0.0013    0.0001
    1488             0.0013    0.0001
    1325             0.0013    0.0001
    1323             0.0013    0.0001
    1218             0.0013    0.0001
    1322             0.0013    0.0001
    1321             0.0013    0.0001
    1230             0.0013    0.0001
    1315             0.0013    0.0001
    1480             0.0013    0.0001
    1229             0.0013    0.0001
    1312             0.0013    0.0001
    1311             0.0013    0.0001
    1224             0.0013    0.0001
    1214             0.0013    0.0001
    1341             0.0013    0.0001
    1185             0.0013    0.0001
    1237             0.0013    0.0001
    1489             0.0013    0.0001
    1440             0.0013    0.0001
    1187             0.0013    0.0001
    1442             0.0013    0.0001
    1291             0.0013    0.0001
    1243             0.0013    0.0001
    1193             0.0013    0.0002
    1449             0.0013    0.0001
    1293             0.0013    0.0001
    1451             0.0013    0.0001
    1197             0.0013    0.0003
    1455             0.0013    0.0001
    1456             0.0013    0.0001
    1201             0.0013    0.0001
    1457             0.0013    0.0001
    1296             0.0013    0.0001
    1205             0.0013    0.0001
    1206             0.0013    0.0001
    1350             0.0013    0.0001
    1459             0.0013    0.0001
    1301             0.0013    0.0001
    1348             0.0013    0.0001
    1238             0.0013    0.0001
    1473             0.0013    0.0001
    1346             0.0013    0.0001
    1155             0.0013    0.0001
       0             0.0013    0.0001
     693             0.0013    0.0001
    1008             0.0013    0.0001
      25             0.0013    0.0001
     787             0.0013    0.0001
     782             0.0013    0.0001
     781             0.0013    0.0001
     779             0.0013    0.0001
     775             0.0013    0.0001
     989             0.0013    0.0001
     319             0.0013    0.0001
     323             0.0013    0.0001
     999             0.0013    0.0001
      12             0.0013    0.0001
     744             0.0013    0.0001
     970             0.0013    0.0001
    1014             0.0013    0.0001
     743             0.0013    0.0002
     736             0.0013    0.0001
    1021             0.0013    0.0002
     418             0.0013    0.0001
    1031             0.0013    0.0001
    1041             0.0013    0.0001
    1049             0.0013    0.0001
     698             0.0013    0.0002
    1151             0.0013    0.0005
    1054             0.0013    0.0001
     974             0.0013    0.0001
     968             0.0013    0.0001
     684             0.0013    0.0001
     921             0.0013    0.0008
     889             0.0013    0.0001
     875             0.0013    0.0002
     873             0.0013    0.0001
     869             0.0013    0.0001
     845             0.0013    0.0001
     280             0.0013    0.0001
     844             0.0013    0.0002
     911             0.0013    0.0001
     914             0.0013    0.0001
     298             0.0013    0.0001
     916             0.0013    0.0001
     833             0.0013    0.0001
     793             0.0013    0.0001
     929             0.0013    0.0001
      41             0.0013    0.0001
     820             0.0013    0.0001
     306             0.0013    0.0001
     940             0.0013    0.0001
     307             0.0013    0.0001
     802             0.0013    0.0008
     941             0.0013    0.0001
     800             0.0013    0.0002
     795             0.0013    0.0001
     794             0.0013    0.0001
    1059             0.0013    0.0003
    1018             0.0013    0.0002
    1111             0.0013    0.0001
     460             0.0013    0.0001
    1087             0.0013    0.0003
     557             0.0013    0.0001
    1089             0.0013    0.0002
    1091             0.0013    0.0002
    1093             0.0013    0.0001
    1114             0.0013    0.0001
     546             0.0013    0.0001
    1119             0.0013    0.0001
    1124             0.0013    0.0001
     542             0.0013    0.0001
     540             0.0013    0.0001
    1127             0.0013    0.0001
    1129             0.0013    0.0001
    1131             0.0013    0.0001
    1134             0.0013    0.0001
     488             0.0013    0.0001
       5             0.0013    0.0003
    1139             0.0013    0.0001
     530             0.0013    0.0001
    1142             0.0013    0.0002
    1148             0.0013    0.0001
     518             0.0013    0.0001
    1150             0.0013    0.0003
     564             0.0013    0.0001
     888             0.0013    0.0001
     457             0.0013    0.0001
    1066             0.0013    0.0001
     679             0.0013    0.0001
     636             0.0013    0.0001
    1082             0.0013    0.0001
     653             0.0013    0.0001
     600             0.0013    0.0001
      10             0.0013    0.0001
     641             0.0013    0.0002
     668             0.0013    0.0001
    1077             0.0013    0.0001
     299             0.0006    0.0001
    1434             0.0006    0.0001
     300             0.0006    0.0001
     458             0.0006    0.0001
    1454             0.0006    0.0001
    1453             0.0006    0.0001
    1452             0.0006    0.0001
    1426             0.0006    0.0001
    1408             0.0006    0.0001
     295             0.0006    0.0001
    1458             0.0006    0.0001
     486             0.0006    0.0001
    1406             0.0006    0.0001
     492             0.0006    0.0001
    1460             0.0006    0.0001
    1461             0.0006    0.0001
    1462             0.0006    0.0001
    1463             0.0006    0.0001
    1404             0.0006    0.0001
    1464             0.0006    0.0001
     443             0.0006    0.0001
    1424             0.0006    0.0001
    1403             0.0006    0.0001
     301             0.0006    0.0001
    1410             0.0006    0.0001
    1450             0.0006    0.0001
     310             0.0006    0.0001
    1436             0.0006    0.0001
    1437             0.0006    0.0001
     342             0.0006    0.0001
    1416             0.0006    0.0001
    1415             0.0006    0.0001
    1433             0.0006    0.0001
    1432             0.0006    0.0001
    1418             0.0006    0.0001
    1431             0.0006    0.0001
    1441             0.0006    0.0001
     311             0.0006    0.0001
    1443             0.0006    0.0001
     467             0.0006    0.0001
     441             0.0006    0.0001
     469             0.0006    0.0001
     450             0.0006    0.0001
     481             0.0006    0.0001
     483             0.0006    0.0001
    1445             0.0006    0.0001
    1446             0.0006    0.0001
    1465             0.0006    0.0001
    1419             0.0006    0.0001
     308             0.0006    0.0001
     439             0.0006    0.0001
     440             0.0006    0.0001
     363             0.0006    0.0001
     451             0.0006    0.0001
    1484             0.0006    0.0001
    1466             0.0006    0.0001
    1535             0.0006    0.0001
    1546             0.0006    0.0001
    1545             0.0006    0.0001
    1544             0.0006    0.0001
    1543             0.0006    0.0001
    1542             0.0006    0.0001
    1541             0.0006    0.0001
    1540             0.0006    0.0001
    1538             0.0006    0.0007
    1537             0.0006    0.0001
    1536             0.0006    0.0001
    1534             0.0006    0.0002
    1467             0.0006    0.0001
    1533             0.0006    0.0001
    1532             0.0006    0.0001
      11             0.0006    0.0001
    1530             0.0006    0.0001
    1529             0.0006    0.0001
    1528             0.0006    0.0001
    1527             0.0006    0.0001
    1526             0.0006    0.0001
    1525             0.0006    0.0001
    1524             0.0006    0.0001
    1547             0.0006    0.0001
    1548             0.0006    0.0001
    1549             0.0006    0.0001
    1550             0.0006    0.0001
    1572             0.0006    0.0001
    1571             0.0006    0.0001
    1570             0.0006    0.0001
       3             0.0006    0.0001
    1568             0.0006    0.0001
    1567             0.0006    0.0001
    1565             0.0006    0.0002
    1564             0.0006    0.0001
    1563             0.0006    0.0001
       8             0.0006    0.0001
    1561             0.0006    0.0001
    1560             0.0006    0.0001
    1559             0.0006    0.0001
    1558             0.0006    0.0001
    1557             0.0006    0.0001
    1556             0.0006    0.0001
    1555             0.0006    0.0001
    1554             0.0006    0.0001
    1553             0.0006    0.0001
    1552             0.0006    0.0001
    1551             0.0006    0.0001
    1523             0.0006    0.0001
    1522             0.0006    0.0001
    1521             0.0006    0.0001
    1494             0.0006    0.0001
    1492             0.0006    0.0001
    1491             0.0006    0.0001
      40             0.0006    0.0001
     143             0.0006    0.0001
    1485             0.0006    0.0001
    1401             0.0006    0.0001
    1483             0.0006    0.0001
     200             0.0006    0.0001
     216             0.0006    0.0001
     217             0.0006    0.0001
     279             0.0006    0.0001
    1478             0.0006    0.0003
    1477             0.0006    0.0001
     281             0.0006    0.0001
    1474             0.0006    0.0001
     284             0.0006    0.0001
    1472             0.0006    0.0001
    1471             0.0006    0.0001
     286             0.0006    0.0001
     290             0.0006    0.0001
    1468             0.0006    0.0001
      39             0.0006    0.0001
      38             0.0006    0.0001
    1519             0.0006    0.0001
      37             0.0006    0.0001
      15             0.0006    0.0001
    1517             0.0006    0.0001
    1516             0.0006    0.0001
    1515             0.0006    0.0001
    1514             0.0006    0.0001
    1513             0.0006    0.0001
    1512             0.0006    0.0001
    1511             0.0006    0.0001
    1510             0.0006    0.0001
      23             0.0006    0.0001
    1508             0.0006    0.0001
    1507             0.0006    0.0001
      24             0.0006    0.0001
    1505             0.0006    0.0001
    1504             0.0006    0.0001
    1502             0.0006    0.0001
      27             0.0006    0.0001
    1500             0.0006    0.0001
    1499             0.0006    0.0001
      28             0.0006    0.0001
    1497             0.0006    0.0001
    1402             0.0006    0.0001
    1152             0.0006    0.0005
     517             0.0006    0.0001
    1234             0.0006    0.0001
     987             0.0006    0.0001
     995             0.0006    0.0001
     997             0.0006    0.0001
     998             0.0006    0.0001
    1002             0.0006    0.0001
    1003             0.0006    0.0001
    1236             0.0006    0.0001
    1235             0.0006    0.0001
    1232             0.0006    0.0001
    1023             0.0006    0.0001
    1009             0.0006    0.0001
    1013             0.0006    0.0001
    1015             0.0006    0.0001
    1227             0.0006    0.0002
    1020             0.0006    0.0001
    1223             0.0006    0.0001
    1022             0.0006    0.0001
    1221             0.0006    0.0001
    1245             0.0006    0.0001
    1246             0.0006    0.0002
     986             0.0006    0.0001
     984             0.0006    0.0001
     935             0.0006    0.0001
     938             0.0006    0.0001
    1268             0.0006    0.0001
    1266             0.0006    0.0001
    1265             0.0006    0.0001
     946             0.0006    0.0001
    1262             0.0006    0.0001
     949             0.0006    0.0001
     950             0.0006    0.0001
    1259             0.0006    0.0001
     959             0.0006    0.0001
    1257             0.0006    0.0001
    1253             0.0006    0.0001
    1252             0.0006    0.0001
    1251             0.0006    0.0001
     981             0.0006    0.0001
     983             0.0006    0.0001
    1220             0.0006    0.0001
    1215             0.0006    0.0001
    1399             0.0006    0.0001
    1130             0.0006    0.0001
    1183             0.0006    0.0001
    1095             0.0006    0.0001
    1180             0.0006    0.0001
    1113             0.0006    0.0001
    1115             0.0006    0.0001
    1126             0.0006    0.0001
    1173             0.0006    0.0001
    1171             0.0006    0.0002
    1135             0.0006    0.0001
    1052             0.0006    0.0001
    1165             0.0006    0.0001
    1136             0.0006    0.0001
    1140             0.0006    0.0001
    1143             0.0006    0.0001
    1146             0.0006    0.0002
    1149             0.0006    0.0002
    1156             0.0006    0.0001
    1154             0.0006    0.0001
    1088             0.0006    0.0001
    1188             0.0006    0.0001
    1189             0.0006    0.0001
    1191             0.0006    0.0001
    1211             0.0006    0.0001
    1210             0.0006    0.0001
    1061             0.0006    0.0001
    1062             0.0006    0.0001
    1064             0.0006    0.0001
    1069             0.0006    0.0001
    1204             0.0006    0.0001
    1070             0.0006    0.0001
    1202             0.0006    0.0001
    1074             0.0006    0.0001
    1076             0.0006    0.0001
    1199             0.0006    0.0001
    1198             0.0006    0.0001
    1196             0.0006    0.0001
    1195             0.0006    0.0001
    1194             0.0006    0.0001
    1086             0.0006    0.0002
     933             0.0006    0.0001
    1272             0.0006    0.0001
     931             0.0006    0.0001
    1351             0.0006    0.0001
    1363             0.0006    0.0002
    1360             0.0006    0.0001
     713             0.0006    0.0001
     723             0.0006    0.0001
     724             0.0006    0.0001
    1356             0.0006    0.0001
    1353             0.0006    0.0001
    1352             0.0006    0.0001
    1349             0.0006    0.0001
    1275             0.0006    0.0001
     749             0.0006    0.0001
     752             0.0006    0.0001
     761             0.0006    0.0001
    1345             0.0006    0.0001
     762             0.0006    0.0001
    1343             0.0006    0.0001
    1338             0.0006    0.0001
    1337             0.0006    0.0001
    1364             0.0006    0.0001
    1365             0.0006    0.0001
    1367             0.0006    0.0001
    1368             0.0006    0.0001
    1397             0.0006    0.0001
     521             0.0006    0.0001
    1395             0.0006    0.0001
    1393             0.0006    0.0001
    1392             0.0006    0.0001
    1391             0.0006    0.0001
    1390             0.0006    0.0001
    1386             0.0006    0.0001
     555             0.0006    0.0001
    1384             0.0006    0.0001
    1383             0.0006    0.0001
    1381             0.0006    0.0002
    1380             0.0006    0.0002
     573             0.0006    0.0001
     616             0.0006    0.0001
    1374             0.0006    0.0001
    1369             0.0006    0.0001
    1336             0.0006    0.0001
    1335             0.0006    0.0001
    1332             0.0006    0.0001
     887             0.0006    0.0001
     895             0.0006    0.0001
    1295             0.0006    0.0001
    1294             0.0006    0.0001
     902             0.0006    0.0001
    1292             0.0006    0.0001
     904             0.0006    0.0001
     907             0.0006    0.0001
    1289             0.0006    0.0001
     908             0.0006    0.0001
    1287             0.0006    0.0001
    1285             0.0006    0.0001
    1284             0.0006    0.0001
    1282             0.0006    0.0001
     919             0.0006    0.0001
    1278             0.0006    0.0001
    1277             0.0006    0.0001
    1276             0.0006    0.0001
     893             0.0006    0.0001
     886             0.0006    0.0001
    1331             0.0006    0.0001
    1304             0.0006    0.0001
     801             0.0006    0.0001
     804             0.0006    0.0008
    1324             0.0006    0.0001
     818             0.0006    0.0001
     821             0.0006    0.0001
     822             0.0006    0.0001
    1319             0.0006    0.0001
     831             0.0006    0.0001
     834             0.0006    0.0001
     837             0.0006    0.0001
    1314             0.0006    0.0001
    1313             0.0006    0.0001
     840             0.0006    0.0001
     849             0.0006    0.0001
     851             0.0006    0.0001
     858             0.0006    0.0001
     862             0.0006    0.0001
    1573             0.0006    0.0001
In [35]:
import networkx as nx
import matplotlib.pyplot as plt
import matplotlib as mpl

# 1) Carga y componente gigante
G_air = read_dir_graph_weighted('airport.txt')
G_air_und = G_air.to_undirected()
comp = max(nx.connected_components(G_air_und), key=len)
Gg = G_air_und.subgraph(comp)

# 2) Calcula centralidades
deg_cent = nx.degree_centrality(Gg)

# 3) Normalización y colormap
values = list(deg_cent.values())
norm   = mpl.colors.Normalize(vmin=min(values), vmax=max(values))
cmap   = plt.cm.viridis
node_colors = [cmap(norm(deg_cent[n])) for n in Gg.nodes()]

# 4) Dibujar en un axes concreto
fig, ax = plt.subplots(figsize=(8, 6))
pos = nx.spring_layout(Gg, seed=42)

nx.draw_networkx_edges(Gg, pos, alpha=0.3, width=0.5, ax=ax)
nx.draw_networkx_nodes(Gg, pos,
                       node_size=50,
                       node_color=node_colors,
                       ax=ax)

# 5) Colorbar ligado a ese mismo ax
sm = mpl.cm.ScalarMappable(cmap=cmap, norm=norm)
sm.set_array([])  
cbar = fig.colorbar(sm, ax=ax)      # <— AQUÍ pasamos fig y ax
cbar.set_label("Degree Centrality", rotation=270, labelpad=15)

ax.set_title("Aeropuertos coloreados por Degree Centrality")
ax.axis('off')
plt.show()
In [57]:
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
import matplotlib as mpl

# 1) Carga y componente gigante
G_air = read_dir_graph_weighted('airport.txt')
G_air_und = G_air.to_undirected()
comp = max(nx.connected_components(G_air_und), key=len)
Gg = G_air_und.subgraph(comp).copy()

# 2) Centralidad de grado
deg_cent = nx.degree_centrality(Gg)

# 3) Layout “explosivo”
#   - k más grande → nodos más separados
#   - iterations suficientes para converger
pos = nx.spring_layout(Gg,
                       k=2,          # distancia ideal entre nodos ( > default )
                       iterations=200,
                       seed=42)

# 4) Opcional: reescalar todo el layout para ampliarlo aún más
scale_factor = 3.0
pos = {n: np.array(coord) * scale_factor for n, coord in pos.items()}

# 5) Preparamos colores y tamaños
values     = list(deg_cent.values())
norm       = mpl.colors.Normalize(vmin=min(values), vmax=max(values))
cmap       = plt.cm.viridis
node_colors= [cmap(norm(deg_cent[n])) for n in Gg.nodes()]
node_sizes = [50 + 300 * norm(deg_cent[n]) for n in Gg.nodes()]

# 6) Dibujar
fig, ax = plt.subplots(figsize=(8, 6))
nx.draw_networkx_edges(Gg, pos, alpha=0.2, width=0.5, ax=ax)
nx.draw_networkx_nodes(Gg, pos,
                       node_size=node_sizes,
                       node_color=node_colors,
                       ax=ax)

# 7) Colorbar
sm = mpl.cm.ScalarMappable(cmap=cmap, norm=norm)
sm.set_array([])
cbar = fig.colorbar(sm, ax=ax, fraction=0.046, pad=0.04)
cbar.set_label("Degree Centrality", rotation=270, labelpad=15)

ax.set_title("Aeropuertos (exploded) por Degree Centrality")
ax.axis('off')
plt.tight_layout()
plt.show()
In [31]:
import networkx as nx
import numpy as np
import random
import matplotlib.pyplot as plt

def robustness(G_orig, centrality, directed=False, trials=20):
    """
    Analiza robustez de G_orig eliminando, en cada paso, todos los enlaces
    de un nodo:
      - Aleatorio (promedia `trials` veces sobre órdenes aleatorios).
      - Dirigido (siguiendo `centrality`, de mayor a menor).
    Para cada paso i (nodos desconectados = i), devuelve:
      * NgN_random[i], NgN_targeted[i]
      * si not directed: E_random[i], E_targeted[i]
    """
    N = G_orig.number_of_nodes()
    # Orden dirigido por centralidad (descendente)
    target_order = sorted(centrality, key=centrality.get, reverse=True)
    
    def one_pass(order):
        G = G_orig.copy()
        Ng = []
        Ef = []
        for node in order:
            # remover todos los enlaces incidentes al nodo
            if directed:
                G.remove_edges_from(list(G.in_edges(node)) + list(G.out_edges(node)))
            else:
                G.remove_edges_from(list(G.edges(node)))
            # tamaño comp gigante
            if directed:
                comps = [len(c) for c in nx.weakly_connected_components(G)]
            else:
                comps = [len(c) for c in nx.connected_components(G)]
            Ng.append(max(comps) / N)
            # eficiencia (solo no dirigido)
            if not directed:
                Ef.append(nx.global_efficiency(G))
        return Ng, Ef

    # 1) Targeted
    Ng_t, Ef_t = one_pass(target_order)

    # 2) Random (promedio)
    all_Ng = []
    all_Ef = []
    nodes = list(G_orig.nodes())
    for _ in range(trials):
        order_rand = random.sample(nodes, N)
        Ng_r, Ef_r = one_pass(order_rand)
        all_Ng.append(Ng_r)
        all_Ef.append(Ef_r)
    Ng_r_mean = np.mean(all_Ng, axis=0)
    Ef_r_mean = None if directed else np.mean(all_Ef, axis=0)

    return {
        'fraction': np.arange(1, N+1)/N,
        'NgN_targeted': Ng_t,
        'NgN_random':  Ng_r_mean,
        **({} if directed else {
          'E_targeted': Ef_t,
          'E_random':   Ef_r_mean
        })
    }

def plot_robustness(curves, directed=False, title=''):
    """
    Dibuja Ng/N (y eficiencia si corresponde) versus fracción de nodos removidos.
    """
    x = curves['fraction']
    plt.figure(figsize=(6,4))
    plt.plot(x, curves['NgN_random'],  '--', label='Ng/N random')
    plt.plot(x, curves['NgN_targeted'], '-',  label='Ng/N targeted')
    if not directed:
        plt.plot(x, curves['E_random'],  '--', label='Eff random')
        plt.plot(x, curves['E_targeted'], '-',  label='Eff targeted')
    plt.xlabel('Fracción de nodos desconectados')
    plt.ylabel('Ng/N  /  Eficiencia')
    plt.title(title)
    plt.legend()
    plt.tight_layout()
    plt.show()


# === Aplicación a tus dos grafos ===

# — 1) Airport (dirigido) —
# Usamos H_air y su PageRank (pr_air) calculados en el punto c)
#curves_air = robustness(H_air, pr_air, directed=True, trials=30)
#plot_robustness(curves_air, directed=True, title='Robustez Airport (Ng/N)')


# — 2) C. elegans (no dirigido) —
# Usamos G_ce y su betweenness (btw_ce)
#curves_ce = robustness(G_ce, btw_ce, directed=False, trials=30)
#plot_robustness(curves_ce, directed=False, title='Robustez C. elegans (Ng/N & E)')
In [32]:
# --- Supuestos previos ---
# H_air = componente fuertemente conexa de Airport (DiGraph)
# G_ce  = grafo no dirigido de C. elegans

import networkx as nx

# 1) Calculamos la centralidad de grado en ambos
deg_air = nx.degree_centrality(H_air)
deg_ce  = nx.degree_centrality(G_ce)

# 2) Ejecutamos el análisis de robustez usando degree centrality
curves_air = robustness(H_air, deg_air, directed=True,  trials=30)
curves_ce  = robustness(G_ce,  deg_ce,  directed=False, trials=30)

# 3) Dibujamos las curvas
plot_robustness(curves_air, directed=True,  title='Robustez Airport (Degree Centrality)')
plot_robustness(curves_ce,  directed=False, title='Robustez C. elegans (Degree Centrality)')
In [37]:
!pip install community
Collecting community
  Downloading community-1.0.0b1.tar.gz (2.2 kB)
  Preparing metadata (setup.py): started
  Preparing metadata (setup.py): finished with status 'done'
Requirement already satisfied: Flask in c:\users\benja\anaconda3\lib\site-packages (from community) (2.2.2)
Requirement already satisfied: requests in c:\users\benja\anaconda3\lib\site-packages (from community) (2.31.0)
Requirement already satisfied: Werkzeug>=2.2.2 in c:\users\benja\anaconda3\lib\site-packages (from Flask->community) (2.2.3)
Requirement already satisfied: Jinja2>=3.0 in c:\users\benja\anaconda3\lib\site-packages (from Flask->community) (3.1.2)
Requirement already satisfied: itsdangerous>=2.0 in c:\users\benja\anaconda3\lib\site-packages (from Flask->community) (2.0.1)
Requirement already satisfied: click>=8.0 in c:\users\benja\anaconda3\lib\site-packages (from Flask->community) (8.0.4)
Requirement already satisfied: charset-normalizer<4,>=2 in c:\users\benja\anaconda3\lib\site-packages (from requests->community) (2.0.4)
Requirement already satisfied: idna<4,>=2.5 in c:\users\benja\anaconda3\lib\site-packages (from requests->community) (3.4)
Requirement already satisfied: urllib3<3,>=1.21.1 in c:\users\benja\anaconda3\lib\site-packages (from requests->community) (1.26.16)
Requirement already satisfied: certifi>=2017.4.17 in c:\users\benja\anaconda3\lib\site-packages (from requests->community) (2023.7.22)
Requirement already satisfied: colorama in c:\users\benja\anaconda3\lib\site-packages (from click>=8.0->Flask->community) (0.4.6)
Requirement already satisfied: MarkupSafe>=2.0 in c:\users\benja\anaconda3\lib\site-packages (from Jinja2>=3.0->Flask->community) (2.1.1)
Building wheels for collected packages: community
  Building wheel for community (setup.py): started
  Building wheel for community (setup.py): finished with status 'done'
  Created wheel for community: filename=community-1.0.0b1-py3-none-any.whl size=2143 sha256=e0dc5cd35857ec721a60b7ccc83c2887a2eab4ddb521fce57ef5df45f25dc6de
  Stored in directory: c:\users\benja\appdata\local\pip\cache\wheels\b7\c9\3f\e222b011e31d3d1de1fd799caed228f770d56f66563014285d
Successfully built community
Installing collected packages: community
Successfully installed community-1.0.0b1
In [45]:
 
Modularidad Louvain (C. elegans): 0.4953
In [41]:
 
Collecting python-louvain
  Downloading python-louvain-0.16.tar.gz (204 kB)
     ---------------------------------------- 0.0/204.6 kB ? eta -:--:--
     -------------------------------------- 204.6/204.6 kB 4.2 MB/s eta 0:00:00
  Preparing metadata (setup.py): started
  Preparing metadata (setup.py): finished with status 'done'
Requirement already satisfied: networkx in c:\users\benja\anaconda3\lib\site-packages (from python-louvain) (3.1)
Requirement already satisfied: numpy in c:\users\benja\anaconda3\lib\site-packages (from python-louvain) (1.24.3)
Building wheels for collected packages: python-louvain
  Building wheel for python-louvain (setup.py): started
  Building wheel for python-louvain (setup.py): finished with status 'done'
  Created wheel for python-louvain: filename=python_louvain-0.16-py3-none-any.whl size=9403 sha256=d23074f1904cb2fdd73b06f9e201fa1d4d382d1d4f0fa5ad226d81a74f16b35c
  Stored in directory: c:\users\benja\appdata\local\pip\cache\wheels\11\c1\e7\f62a211c636275e2da798bf0c307a3ae79aeddaf2524a03ce4
Successfully built python-louvain
Installing collected packages: python-louvain
Successfully installed python-louvain-0.16
Note: you may need to restart the kernel to use updated packages.
In [51]:
# 0) Instala dependencia para Louvain
# pip install python-louvain

import networkx as nx
import community as community_louvain   # python-louvain
import matplotlib.pyplot as plt

from networkx.algorithms.community import louvain_communities
from networkx.algorithms.community.quality import modularity

def detectar_comunidades_louvain_nx(G):
    coms = louvain_communities(G, weight='weight')
    mod  = modularity(G, coms, weight='weight')
    # convertir lista de sets a dict nodo→comunidad
    partition = {n:i for i, comm in enumerate(coms) for n in comm}
    return partition, mod

part_ce2, mod_ce2 = detectar_comunidades_louvain_nx(G_ce)
print(f"Modularidad Louvain-NX (C. elegans): {mod_ce2:.4f}")


def detectar_comunidades_girvan_newman(G, k=None):
    """
    k = número deseado de comunidades finales.
    Si k=None toma la primera división (2 comunidades).
    """
    comp_gen = nx.community.girvan_newman(G)
    if k is None:
        first_level = next(comp_gen)
        return list(first_level)
    else:
        for communities in comp_gen:
            if len(communities) >= k:
                return list(communities)
    return None

def dibujar_comunidades(G, partition, pos=None, title=""):
    """
    partition: dict nodo→comunidad
    pos: posiciones (si ya las cargaste con pickle, úsalas)
    """
    if pos is None:
        pos = nx.spring_layout(G, seed=42)
    # agrupar nodos por comunidad
    comm2nodes = {}
    for n, comm in partition.items():
        comm2nodes.setdefault(comm, []).append(n)
    # paleta
    cmap = plt.cm.tab20 
    plt.figure(figsize=(8,6))
    for comm, nodes in comm2nodes.items():
        nx.draw_networkx_nodes(
            G, pos,
            nodelist=nodes,
            node_size=50,
            node_color=[cmap(comm % 20)],
            label=f"c{comm}"
        )
    nx.draw_networkx_edges(G, pos, alpha=0.2, width=0.5)
    plt.title(title)
    plt.legend(scatterpoints=1, fontsize=8)
    plt.axis('off')
    plt.show()

# ————————————————
# Ejemplo sobre C. elegans
G_ce = read_graph_weighted("celegans.txt").to_undirected()
# 1) Louvain
part_ce, mod_ce = detectar_comunidades_louvain_nx(G_ce)
print(f"Modularidad Louvain (C.elegans): {mod_ce:.4f}")
dibujar_comunidades(G_ce, part_ce, title="C.elegans – Louvain")

# 2) Girvan–Newman (2 comunidades)
coms_gn = detectar_comunidades_girvan_newman(G_ce, k=2)
print(f"Girvan-Newman 2 comunidades → tamaños: {[len(c) for c in coms_gn]}")
# para dibujar, convertimos la lista de sets a dict nodo→índice
part_gn = {n: i for i, comm in enumerate(coms_gn) for n in comm}
dibujar_comunidades(G_ce, part_gn, title="C.elegans – Girvan-Newman")

# ————————————————
# Ejemplo sobre Airport
#G_air = read_dir_graph_weighted("airport.txt").to_undirected()
#part_air, mod_air = detectar_comunidades_louvain_nx(G_air)
#print(f"Modularidad Louvain (Airport): {mod_air:.4f}")

# grafo no dirigido de la componente gigante
# 1) Carga y componente gigante (no dirigido)
G_air = read_dir_graph_weighted('airport.txt').to_undirected()
comp   = max(nx.connected_components(G_air), key=len)
Gg     = G_air.subgraph(comp).copy()

# 2) Detección de comunidades con Louvain de NX (unweighted)
#    weight=None fuerza que ignore cualquier atributo 'weight'
communities = louvain_communities(Gg, weight=None)
mod_score  = modularity(Gg, communities, weight=None)

print(f"Modularidad Louvain Airport (unweighted): {mod_score:.4f}")

# 3) Preparamos un dict nodo→comunidad para colorear
partition = {n:i for i, comm in enumerate(communities) for n in comm}

# 4) Dibujado
pos   = nx.spring_layout(Gg, seed=42)
cmap  = plt.cm.tab20
colors= [cmap(partition[n] % 20) for n in Gg.nodes()]

plt.figure(figsize=(8,6))
nx.draw_networkx_edges(Gg, pos, alpha=0.2, width=0.5)
nx.draw_networkx_nodes(Gg, pos,
                       node_size=50,
                       node_color=colors)
plt.title(f"Airport – Louvain (unweighted)\nmodularidad={mod_score:.4f}")
plt.axis('off')
plt.show()


# Girvan–Newman en Airport puede ser muy lento por tamaño; pruebes sobre muestra:
# subG = G_air.subgraph(list(G_air.nodes())[:200])
# … aplicar mismo flujo sobre subG …
Modularidad Louvain-NX (C. elegans): 0.4943
Modularidad Louvain (C.elegans): 0.4901
Girvan-Newman 2 comunidades → tamaños: [296, 1]
Modularidad Louvain (unweighted): 0.3295
In [53]:
# grafo no dirigido de la componente gigante
# 1) Carga y componente gigante (no dirigido)
G_air = read_dir_graph_weighted('airport.txt').to_undirected()
comp   = max(nx.connected_components(G_air), key=len)
Gg     = G_air.subgraph(comp).copy()

# 2) Detección de comunidades con Louvain de NX (unweighted)
#    weight=None fuerza que ignore cualquier atributo 'weight'
communities = louvain_communities(Gg, weight='weight')
mod_score  = modularity(Gg, communities, weight='weight')

print(f"Modularidad Louvain (weighted): {mod_score:.4f}")

# 3) Preparamos un dict nodo→comunidad para colorear
partition = {n:i for i, comm in enumerate(communities) for n in comm}

# 4) Dibujado
pos   = nx.spring_layout(Gg, seed=42)
cmap  = plt.cm.tab20
colors= [cmap(partition[n] % 20) for n in Gg.nodes()]

plt.figure(figsize=(8,6))
nx.draw_networkx_edges(Gg, pos, alpha=0.2, width=0.5)
nx.draw_networkx_nodes(Gg, pos,
                       node_size=50,
                       node_color=colors)
plt.title(f"Airport – Louvain (weighted)\nmodularidad={mod_score:.4f}")
plt.axis('off')
plt.show()
Modularidad Louvain (weighted): 4.3635